From: Tanya Lattner Date: Wed, 11 Jul 2012 23:02:10 +0000 (+0000) Subject: Add OpenCL metadata for kernel arg names. This output is controlled via a flag as... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=198871cc90375246d8692680467ff6e810edac36;p=clang Add OpenCL metadata for kernel arg names. This output is controlled via a flag as noted in the OpenCL Spec. Includes a test case. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160092 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index a68353a939..cf8ef814fc 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -39,6 +39,7 @@ def clang_i_Group : OptionGroup<"">, Group; def m_Group : OptionGroup<"">, Group; def m_x86_Features_Group : OptionGroup<"">, Group; def m_hexagon_Features_Group : OptionGroup<"">, Group; +def opencl_Group : OptionGroup<"">; def u_Group : OptionGroup<"">; def pedantic_Group : OptionGroup<"">, @@ -247,6 +248,8 @@ def bind__at__load : Flag<"-bind_at_load">; def bundle__loader : Separate<"-bundle_loader">; def bundle : Flag<"-bundle">; def b : JoinedOrSeparate<"-b">, Flags<[Unsupported]>; +def cl_kernel_arg_info : Flag<"-cl-kernel-arg-info">, Flags<[CC1Option]>, Group, +HelpText<"OpenCL only. This option allows the compiler to store information about the arguments of a kernel(s)"> ; def client__name : JoinedOrSeparate<"-client_name">; def combine : Flag<"-combine">, Flags<[DriverOption, Unsupported]>; def compatibility__version : JoinedOrSeparate<"-compatibility_version">; diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h index b36f5f2751..c8d6578b29 100644 --- a/include/clang/Frontend/CodeGenOptions.h +++ b/include/clang/Frontend/CodeGenOptions.h @@ -71,6 +71,7 @@ public: ///< subroutine. unsigned EmitGcovArcs : 1; ///< Emit coverage data files, aka. GCDA. unsigned EmitGcovNotes : 1; ///< Emit coverage "notes" files, aka GCNO. + unsigned EmitOpenCLArgMetadata : 1; /// Emit OpenCL kernel arg metadata. unsigned ForbidGuardVariables : 1; ///< Issue errors if C++ guard variables ///< are required unsigned FunctionSections : 1; ///< Set when -ffunction-sections is enabled @@ -199,6 +200,7 @@ public: EmitDeclMetadata = 0; EmitGcovArcs = 0; EmitGcovNotes = 0; + EmitOpenCLArgMetadata = 0; ForbidGuardVariables = 0; FunctionSections = 0; HiddenWeakTemplateVTables = 0; diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index c40b42193f..954db7f8c0 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -252,6 +252,33 @@ void CodeGenFunction::EmitMCountInstrumentation() { Builder.CreateCall(MCountFn); } +// OpenCL v1.2 s5.6.4.6 allows the compiler to store kernel argument +// information in the program executable. The argument information stored +// includes the argument name, its type, the address and access qualifiers used. +// FIXME: Add type, address, and access qualifiers. +static void GenOpenCLArgMetadata(const FunctionDecl *FD, llvm::Function *Fn, + CodeGenModule &CGM,llvm::LLVMContext &Context, + llvm::SmallVector &kernelMDArgs) { + + // Create MDNodes that represents the kernel arg metadata. + // Each MDNode is a list in the form of "key", N number of values which is + // the same number of values as their are kernel arguments. + + // MDNode for the kernel argument names. + SmallVector argNames; + argNames.push_back(llvm::MDString::get(Context, "kernel_arg_name")); + + for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) { + const ParmVarDecl *parm = FD->getParamDecl(i); + + // Get argument name. + argNames.push_back(llvm::MDString::get(Context, parm->getName())); + + } + // Add MDNode to the list of all metadata. + kernelMDArgs.push_back(llvm::MDNode::get(Context, argNames)); +} + void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD, llvm::Function *Fn) { @@ -263,6 +290,9 @@ void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD, llvm::SmallVector kernelMDArgs; kernelMDArgs.push_back(Fn); + if (CGM.getCodeGenOpts().EmitOpenCLArgMetadata) + GenOpenCLArgMetadata(FD, Fn, CGM, Context, kernelMDArgs); + if (FD->hasAttr()) { llvm::SmallVector attrMDArgs; attrMDArgs.push_back(llvm::MDString::get(Context, "work_group_size_hint")); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index cf08913e3b..016783b1dc 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -210,6 +210,8 @@ static void CodeGenOptsToArgs(const CodeGenOptions &Opts, ToArgsList &Res) { Res.push_back("-femit-coverage-data"); if (Opts.EmitGcovNotes) Res.push_back("-femit-coverage-notes"); + if (Opts.EmitOpenCLArgMetadata) + Res.push_back("-cl-kernel-arg-info"); if (!Opts.MergeAllConstants) Res.push_back("-fno-merge-all-constants"); if (Opts.NoCommon) @@ -1258,6 +1260,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.InstrumentForProfiling = Args.hasArg(OPT_pg); Opts.EmitGcovArcs = Args.hasArg(OPT_femit_coverage_data); Opts.EmitGcovNotes = Args.hasArg(OPT_femit_coverage_notes); + Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info); Opts.CoverageFile = Args.getLastArgValue(OPT_coverage_file); Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir); Opts.LinkBitcodeFile = Args.getLastArgValue(OPT_mlink_bitcode_file); diff --git a/test/CodeGenOpenCL/kernel-arg-info.cl b/test/CodeGenOpenCL/kernel-arg-info.cl new file mode 100644 index 0000000000..9d52736a76 --- /dev/null +++ b/test/CodeGenOpenCL/kernel-arg-info.cl @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -cl-kernel-arg-info -emit-llvm -o - | FileCheck %s + +kernel void foo(int *X, int Y, int anotherArg) { + *X = Y + anotherArg; +} + +// CHECK: metadata !{metadata !"kernel_arg_name", metadata !"X", metadata !"Y", metadata !"anotherArg"}