yaxunl retitled this revision from "[OpenCL] Include opencl-c.h by default as a module" to "[OpenCL] Include opencl-c.h by default as a clang module". yaxunl updated the summary for this revision. yaxunl updated this revision to Diff 58830. yaxunl added a comment.
Revised as Anastasia suggested. Add option -finclude-default-header to include OpenCL default header file, which is off by default. Add test to make sure the AST of the header is really cached and works for different OpenCL versions. http://reviews.llvm.org/D20444 Files: include/clang/Basic/LangOptions.def include/clang/Driver/CC1Options.td include/clang/Frontend/CompilerInvocation.h lib/Frontend/CompilerInvocation.cpp lib/Headers/module.modulemap test/Headers/opencl-c-header.cl
Index: test/Headers/opencl-c-header.cl =================================================================== --- test/Headers/opencl-c-header.cl +++ test/Headers/opencl-c-header.cl @@ -1,9 +1,61 @@ // RUN: %clang_cc1 -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL1.1| FileCheck %s // RUN: %clang_cc1 -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL1.2| FileCheck %s -// RUN: %clang_cc1 -internal-isystem ../../lib/Headers -include opencl-c.h -fblocks -emit-llvm -o - %s -cl-std=CL2.0| FileCheck %s +// RUN: %clang_cc1 -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL2.0| FileCheck --check-prefix=CHECK20 %s +// RUN: %clang_cc1 -emit-llvm -verify -DNO_HEADER %s +// RUN: %clang_cc1 -finclude-default-header -emit-llvm -o - %s | FileCheck %s // CHECK: _Z16convert_char_rtec +// CHECK20: _Z3ctzc + +// Test including the default header as a module. +// The module should be compiled only once and loaded from cache afterwards. + +// === +// Clear current directory. +// RUN: rm -rf %t +// RUN: mkdir -p %t + +// === +// Compile for OpenCL 1.0 for the first time. A module should be generated. +// RUN: %clang_cc1 -cc1 -emit-llvm -o - -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash %s | FileCheck %s +// RUN: cp %t/opencl_c.pcm %t/1_0.pcm + +// === +// Compile for OpenCL 1.0 for the second time. The module should not change. +// RUN: %clang_cc1 -cc1 -emit-llvm -o - -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash %s | FileCheck %s +// RUN: diff %t/1_0.pcm %t/opencl_c.pcm +// RUN: rm %t/opencl_c.pcm + +// === +// Compile for OpenCL 2.0 for the first time. The module should change. +// RUN: %clang_cc1 -cc1 -emit-llvm -o - -cl-std=CL2.0 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash %s | FileCheck --check-prefix=CHECK20 %s +// RUN: not diff %t/1_0.pcm %t/opencl_c.pcm +// RUN: cp %t/opencl_c.pcm %t/2_0.pcm + +// === +// Compile for OpenCL 2.0 for the second time. The module should not change. +// RUN: %clang_cc1 -cc1 -emit-llvm -o - -cl-std=CL2.0 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash %s | FileCheck --check-prefix=CHECK20 %s +// RUN: diff %t/2_0.pcm %t/opencl_c.pcm + +// Check cached module works for different OpenCL versions. +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: %clang_cc1 -cc1 -emit-llvm -o - -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t %s | FileCheck %s +// RUN: %clang_cc1 -cc1 -emit-llvm -o - -cl-std=CL2.0 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t %s | FileCheck --check-prefix=CHECK20 %s +// RUN: %clang_cc1 -cc1 -emit-llvm -o - -cl-std=CL2.0 -triple amdgcn--amdhsa -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t %s | FileCheck --check-prefix=CHECK20 %s +// RUN: %clang_cc1 -cc1 -emit-llvm -o - -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t %s | FileCheck %s +// RUN: %clang_cc1 -cc1 -emit-llvm -o - -cl-std=CL2.0 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t %s | FileCheck --check-prefix=CHECK20 %s +// RUN: %clang_cc1 -cc1 -emit-llvm -o - -cl-std=CL2.0 -triple amdgcn--amdhsa -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t %s | FileCheck --check-prefix=CHECK20 %s + char f(char x) { +#if __OPENCL_C_VERSION__ != CL_VERSION_2_0 return convert_char_rte(x); +#ifdef NO_HEADER + //expected-warning@-2{{implicit declaration of function 'convert_char_rte' is invalid in C99}} +#endif //NO_HEADER + +#else //__OPENCL_C_VERSION__ + return ctz(x); +#endif //__OPENCL_C_VERSION__ } Index: lib/Headers/module.modulemap =================================================================== --- lib/Headers/module.modulemap +++ lib/Headers/module.modulemap @@ -157,3 +157,8 @@ module _Builtin_stddef_max_align_t [system] [extern_c] { header "__stddef_max_align_t.h" } + +module opencl_c { + requires opencl + header "opencl-c.h" +} Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -1405,6 +1405,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, const llvm::Triple &T, + PreprocessorOptions &PPOpts, LangStandard::Kind LangStd) { // Set some properties which depend solely on the input kind; it would be nice // to move these to the language standard, and have the driver resolve the @@ -1486,6 +1487,10 @@ Opts.DefaultFPContract = 1; Opts.NativeHalfType = 1; Opts.NativeHalfArgsAndReturns = 1; + // Include default header file for OpenCL. + if (Opts.IncludeDefaultHeader) { + PPOpts.Includes.push_back("opencl-c.h"); + } } Opts.CUDA = IK == IK_CUDA || IK == IK_PreprocessedCuda || @@ -1526,6 +1531,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, const TargetOptions &TargetOpts, + PreprocessorOptions &PPOpts, DiagnosticsEngine &Diags) { // FIXME: Cleanup per-file based stuff. LangStandard::Kind LangStd = LangStandard::lang_unspecified; @@ -1594,8 +1600,10 @@ LangStd = OpenCLLangStd; } + Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header); + llvm::Triple T(TargetOpts.Triple); - CompilerInvocation::setLangDefaults(Opts, IK, T, LangStd); + CompilerInvocation::setLangDefaults(Opts, IK, T, PPOpts, LangStd); // We abuse '-f[no-]gnu-keywords' to force overriding all GNU-extension // keywords. This behavior is provided by GCC's poorly named '-fasm' flag, @@ -1771,7 +1779,8 @@ Opts.RTTI = Opts.CPlusPlus && !Args.hasArg(OPT_fno_rtti); Opts.RTTIData = Opts.RTTI && !Args.hasArg(OPT_fno_rtti_data); - Opts.Blocks = Args.hasArg(OPT_fblocks); + Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL + && Opts.OpenCLVersion >= 200 && !Args.hasArg(OPT_fno_blocks)); Opts.BlocksRuntimeOptional = Args.hasArg(OPT_fblocks_runtime_optional); Opts.Coroutines = Args.hasArg(OPT_fcoroutines); Opts.Modules = Args.hasArg(OPT_fmodules); @@ -2257,7 +2266,8 @@ Diags, LangOpts.Sanitize); } else { // Other LangOpts are only initialzed when the input is not AST or LLVM IR. - ParseLangArgs(LangOpts, Args, DashX, Res.getTargetOpts(), Diags); + ParseLangArgs(LangOpts, Args, DashX, Res.getTargetOpts(), + Res.getPreprocessorOpts(), Diags); if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC) LangOpts.ObjCExceptions = 1; } Index: include/clang/Frontend/CompilerInvocation.h =================================================================== --- include/clang/Frontend/CompilerInvocation.h +++ include/clang/Frontend/CompilerInvocation.h @@ -154,9 +154,10 @@ /// \param Opts - The LangOptions object to set up. /// \param IK - The input language. /// \param T - The target triple. + /// \param PPOpts - The PreprocessorOptions affected. /// \param LangStd - The input language standard. static void setLangDefaults(LangOptions &Opts, InputKind IK, - const llvm::Triple &T, + const llvm::Triple &T, PreprocessorOptions &PPOpts, LangStandard::Kind LangStd = LangStandard::lang_unspecified); /// \brief Retrieve a module hash string that is suitable for uniquely Index: include/clang/Driver/CC1Options.td =================================================================== --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -612,6 +612,8 @@ HelpText<"Allow function arguments and returns of type half">; def fdefault_calling_conv_EQ : Joined<["-"], "fdefault-calling-conv=">, HelpText<"Set default MS calling convention">; +def finclude_default_header : Flag<["-"], "finclude-default-header">, + HelpText<"Include the default header file for OpenCL">; // C++ TSes. def fcoroutines : Flag<["-"], "fcoroutines">, Index: include/clang/Basic/LangOptions.def =================================================================== --- include/clang/Basic/LangOptions.def +++ include/clang/Basic/LangOptions.def @@ -217,7 +217,7 @@ LANGOPT(ObjCSubscriptingLegacyRuntime , 1, 0, "Subscripting support in legacy ObjectiveC runtime") LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map") ENUM_LANGOPT(AddressSpaceMapMangling , AddrSpaceMapMangling, 2, ASMM_Target, "OpenCL address space map mangling mode") - +LANGOPT(IncludeDefaultHeader, 1, 0, "Include default header file for OpenCL") BENIGN_LANGOPT(DelayedTemplateParsing , 1, 0, "delayed template parsing") LANGOPT(BlocksRuntimeOptional , 1, 0, "optional blocks runtime")
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits