From: Yaxun Liu Date: Mon, 20 Jun 2016 19:26:00 +0000 (+0000) Subject: [OpenCL] Include opencl-c.h by default as a clang module X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5a7e51b93eea78a78d0664cb6a940e1d5abba139;p=clang [OpenCL] Include opencl-c.h by default as a clang module Include opencl-c.h by default as a module to utilize the automatic AST caching mechanism of clang modules. Add an option -finclude-default-header to enable default header for OpenCL, which is off by default. Differential Revision: http://reviews.llvm.org/D20444 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@273191 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def index 0f67ed3a3b..3fb4e9732d 100644 --- a/include/clang/Basic/LangOptions.def +++ b/include/clang/Basic/LangOptions.def @@ -218,7 +218,7 @@ LANGOPT(ObjCWeak , 1, 0, "Objective-C __weak in ARC and MRC files") 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") diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 39aac92dc0..f8168448ea 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -612,6 +612,8 @@ def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-r 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">, diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h index 36d997fe9c..0d5008e9a6 100644 --- a/include/clang/Frontend/CompilerInvocation.h +++ b/include/clang/Frontend/CompilerInvocation.h @@ -155,9 +155,10 @@ public: /// \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 diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 0854abedfe..4a3c31b1d1 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1459,6 +1459,7 @@ bool isOpenCL(LangStandard::Kind LangStd) { 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 @@ -1543,6 +1544,10 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, 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 || @@ -1589,6 +1594,7 @@ static Visibility parseVisibility(Arg *arg, ArgList &args, 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; @@ -1660,8 +1666,10 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, 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, @@ -2331,7 +2339,8 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, 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; } diff --git a/lib/Headers/module.modulemap b/lib/Headers/module.modulemap index 04ef9e8829..3e40d2c08d 100644 --- a/lib/Headers/module.modulemap +++ b/lib/Headers/module.modulemap @@ -157,3 +157,8 @@ module _Builtin_intrinsics [system] [extern_c] { module _Builtin_stddef_max_align_t [system] [extern_c] { header "__stddef_max_align_t.h" } + +module opencl_c { + requires opencl + header "opencl-c.h" +} diff --git a/test/Headers/opencl-c-header.cl b/test/Headers/opencl-c-header.cl index 27a93e224e..1527a7c5e4 100644 --- a/test/Headers/opencl-c-header.cl +++ b/test/Headers/opencl-c-header.cl @@ -1,33 +1,90 @@ // RUN: %clang_cc1 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL1.1| FileCheck %s // RUN: %clang_cc1 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL1.2| FileCheck %s -// RUN: %clang_cc1 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -fblocks -emit-llvm -o - %s -cl-std=CL2.0| FileCheck %s +// RUN: %clang_cc1 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -fblocks -emit-llvm -o - %s -cl-std=CL2.0| FileCheck --check-prefix=CHECK20 %s // RUN: %clang_cc1 -triple spir64-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple spir64-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL1.1| FileCheck %s // RUN: %clang_cc1 -triple spir64-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL1.2| FileCheck %s -// RUN: %clang_cc1 -triple spir64-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -fblocks -emit-llvm -o - %s -cl-std=CL2.0| FileCheck %s +// RUN: %clang_cc1 -triple spir64-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -fblocks -emit-llvm -o - %s -cl-std=CL2.0| FileCheck --check-prefix=CHECK20 %s // RUN: %clang_cc1 -triple amdgcn-unknown-amdhsa -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple amdgcn-unknown-amdhsa -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL1.1| FileCheck %s // RUN: %clang_cc1 -triple amdgcn-unknown-amdhsa -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL1.2| FileCheck %s -// RUN: %clang_cc1 -triple amdgcn-unknown-amdhsa -internal-isystem ../../lib/Headers -include opencl-c.h -fblocks -emit-llvm -o - %s -cl-std=CL2.0| FileCheck %s +// RUN: %clang_cc1 -triple amdgcn-unknown-amdhsa -internal-isystem ../../lib/Headers -include opencl-c.h -fblocks -emit-llvm -o - %s -cl-std=CL2.0| FileCheck --check-prefix=CHECK20 %s // RUN: %clang_cc1 -triple ppc64-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple ppc64-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL1.1| FileCheck %s // RUN: %clang_cc1 -triple ppc64-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL1.2| FileCheck %s -// RUN: %clang_cc1 -triple ppc64-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -fblocks -emit-llvm -o - %s -cl-std=CL2.0| FileCheck %s +// RUN: %clang_cc1 -triple ppc64-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -fblocks -emit-llvm -o - %s -cl-std=CL2.0| FileCheck --check-prefix=CHECK20 %s // RUN: %clang_cc1 -triple powerpc-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple powerpc-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL1.1| FileCheck %s // RUN: %clang_cc1 -triple powerpc-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL1.2| FileCheck %s -// RUN: %clang_cc1 -triple powerpc-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -fblocks -emit-llvm -o - %s -cl-std=CL2.0| FileCheck %s +// RUN: %clang_cc1 -triple powerpc-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -fblocks -emit-llvm -o - %s -cl-std=CL2.0| FileCheck --check-prefix=CHECK20 %s // RUN: %clang_cc1 -triple nvptx-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple nvptx-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL1.1| FileCheck %s // RUN: %clang_cc1 -triple nvptx-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL1.2| FileCheck %s -// RUN: %clang_cc1 -triple nvptx-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -fblocks -emit-llvm -o - %s -cl-std=CL2.0| FileCheck %s +// RUN: %clang_cc1 -triple nvptx-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -fblocks -emit-llvm -o - %s -cl-std=CL2.0| FileCheck --check-prefix=CHECK20 %s // RUN: %clang_cc1 -triple nvptx64-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple nvptx64-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL1.1| FileCheck %s // RUN: %clang_cc1 -triple nvptx64-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -cl-std=CL1.2| FileCheck %s -// RUN: %clang_cc1 -triple nvptx64-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -fblocks -emit-llvm -o - %s -cl-std=CL2.0| FileCheck %s +// RUN: %clang_cc1 -triple nvptx64-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -fblocks -emit-llvm -o - %s -cl-std=CL2.0| FileCheck --check-prefix=CHECK20 %s +// RUN: %clang_cc1 -finclude-default-header -emit-llvm -o - %s | FileCheck %s // CHECK: _Z16convert_char_rtec +// CHECK-NOT: _Z3ctzc +// CHECK20: _Z3ctzc +// CHECK20-NOT: _Z16convert_char_rtec +// CHECK-MOD: Reading modules + +// Test including the default header as a module. +// The module should be compiled only once and loaded from cache afterwards. +// Change the directory mode to read only to make sure no new modules are created. +// Check time report to make sure module is used. + +// === +// 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 -triple spir-unknown-unknown -emit-llvm -o - -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK --check-prefix=CHECK-MOD %s +// RUN: chmod u-w %t/opencl_c.pcm + +// === +// Compile for OpenCL 1.0 for the second time. The module should not be re-created. +// RUN: %clang_cc1 -triple spir-unknown-unknown -emit-llvm -o - -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK --check-prefix=CHECK-MOD %s +// RUN: chmod u+w %t/opencl_c.pcm +// RUN: mv %t/opencl_c.pcm %t/1_0.pcm + +// === +// Compile for OpenCL 2.0 for the first time. The module should change. +// RUN: %clang_cc1 -triple spir-unknown-unknown -emit-llvm -o - -cl-std=CL2.0 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK20 --check-prefix=CHECK-MOD %s +// RUN: not diff %t/1_0.pcm %t/opencl_c.pcm +// RUN: chmod u-w %t/opencl_c.pcm + +// === +// Compile for OpenCL 2.0 for the second time. The module should not change. +// RUN: %clang_cc1 -triple spir-unknown-unknown -emit-llvm -o - -cl-std=CL2.0 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK20 --check-prefix=CHECK-MOD %s + +// Check cached module works for different OpenCL versions. +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: %clang_cc1 -triple spir-unknown-unknown -emit-llvm -o - -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK --check-prefix=CHECK-MOD %s +// RUN: %clang_cc1 -triple spir-unknown-unknown -emit-llvm -o - -cl-std=CL2.0 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK20 --check-prefix=CHECK-MOD %s +// RUN: %clang_cc1 -triple amdgcn--amdhsa -emit-llvm -o - -cl-std=CL2.0 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK20 --check-prefix=CHECK-MOD %s +// RUN: chmod u-w %t/* +// RUN: %clang_cc1 -triple spir-unknown-unknown -emit-llvm -o - -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK --check-prefix=CHECK-MOD %s +// RUN: %clang_cc1 -triple spir-unknown-unknown -emit-llvm -o - -cl-std=CL2.0 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK20 --check-prefix=CHECK-MOD %s +// RUN: %clang_cc1 -triple amdgcn--amdhsa -emit-llvm -o - -cl-std=CL2.0 -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ftime-report %s 2>&1 | FileCheck --check-prefix=CHECK20 --check-prefix=CHECK-MOD %s +// RUN: chmod u+w %t/* + 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__ }