diff options
-rw-r--r-- | include/clang/Driver/Options.td | 3 | ||||
-rw-r--r-- | include/clang/Frontend/CodeGenOptions.h | 2 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 30 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 3 | ||||
-rw-r--r-- | test/CodeGenOpenCL/kernel-arg-info.cl | 7 |
5 files changed, 45 insertions, 0 deletions
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<"<clang i group>">, Group<i_Group>; def m_Group : OptionGroup<"<m group>">, Group<CompileOnly_Group>; def m_x86_Features_Group : OptionGroup<"<m x86 features group>">, Group<m_Group>; def m_hexagon_Features_Group : OptionGroup<"<m hexagon features group>">, Group<m_Group>; +def opencl_Group : OptionGroup<"<opencl group>">; def u_Group : OptionGroup<"<u group>">; def pedantic_Group : OptionGroup<"<pedantic group>">, @@ -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<opencl_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 <llvm::Value*, 5> &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<llvm::Value*, 8> 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 <llvm::Value*, 5> kernelMDArgs; kernelMDArgs.push_back(Fn); + if (CGM.getCodeGenOpts().EmitOpenCLArgMetadata) + GenOpenCLArgMetadata(FD, Fn, CGM, Context, kernelMDArgs); + if (FD->hasAttr<WorkGroupSizeHintAttr>()) { llvm::SmallVector <llvm::Value*, 5> 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"} |