[OpenCL] Override supported OpenCL extensions with -cl-ext option

Summary:
This patch adds a command line option '-cl-ext' to control a set of
supported OpenCL extensions. Option accepts a comma-separated list
of extensions prefixed with '+' or '-'.

It can be used together with a target triple to override support for some
extensions:

  // spir target supports all extensions, but we want to disable fp64
  clang -cc1 -triple spir-unknown-unknown -cl-ext=-cl_khr_fp64

Special 'all' extension allows to enable or disable all possible
extensions:

  // only fp64 will be supported
  clang -cc1 -triple spir-unknown-unknown -cl-ext=-all,+cl_khr_fp64

Patch by asavonic (Andrew Savonichev).

Reviewers: joey, yaxunl

Subscribers: yaxunl, bader, Anastasia, cfe-commits

Differential Revision: https://reviews.llvm.org/D23712

llvm-svn: 285700
This commit is contained in:
Alexey Bader 2016-11-01 15:50:52 +00:00
parent 04ef115ff7
commit 0ea075328e
7 changed files with 80 additions and 4 deletions

View File

@ -15,6 +15,8 @@
#ifndef LLVM_CLANG_BASIC_OPENCLOPTIONS_H
#define LLVM_CLANG_BASIC_OPENCLOPTIONS_H
#include "llvm/ADT/StringRef.h"
namespace clang {
/// \brief OpenCL supported extensions and optional core features
@ -28,9 +30,39 @@ public:
#include "clang/Basic/OpenCLExtensions.def"
}
// Enable all options.
void setAll() {
#define OPENCLEXT(nm) nm = 1;
// Enable or disable all options.
void setAll(bool Enable = true) {
#define OPENCLEXT(nm) nm = Enable;
#include "clang/Basic/OpenCLExtensions.def"
}
/// \brief Enable or disable support for OpenCL extensions
/// \param Ext name of the extension optionally prefixed with
/// '+' or '-'
/// \param Enable used when \p Ext is not prefixed by '+' or '-'
void set(llvm::StringRef Ext, bool Enable = true) {
assert(!Ext.empty() && "Extension is empty.");
switch (Ext[0]) {
case '+':
Enable = true;
Ext = Ext.drop_front();
break;
case '-':
Enable = false;
Ext = Ext.drop_front();
break;
}
if (Ext.equals("all")) {
setAll(Enable);
return;
}
#define OPENCLEXT(nm) \
if (Ext.equals(#nm)) { \
nm = Enable; \
}
#include "clang/Basic/OpenCLExtensions.def"
}

View File

@ -995,6 +995,13 @@ public:
/// \brief Set supported OpenCL extensions and optional core features.
virtual void setSupportedOpenCLOpts() {}
/// \brief Set supported OpenCL extensions as written on command line
virtual void setOpenCLExtensionOpts() {
for (const auto &Ext : getTargetOpts().OpenCLExtensionsAsWritten) {
getTargetOpts().SupportedOpenCLOptions.set(Ext);
}
}
/// \brief Get supported OpenCL extensions and optional core features.
OpenCLOptions &getSupportedOpenCLOpts() {
return getTargetOpts().SupportedOpenCLOptions;

View File

@ -58,6 +58,10 @@ public:
/// Supported OpenCL extensions and optional core features.
OpenCLOptions SupportedOpenCLOptions;
/// \brief The list of OpenCL extensions to enable or disable, as written on
/// the command line.
std::vector<std::string> OpenCLExtensionsAsWritten;
};
} // end namespace clang

View File

@ -687,6 +687,13 @@ def token_cache : Separate<["-"], "token-cache">, MetaVarName<"<path>">,
def detailed_preprocessing_record : Flag<["-"], "detailed-preprocessing-record">,
HelpText<"include a detailed record of preprocessing actions">;
//===----------------------------------------------------------------------===//
// OpenCL Options
//===----------------------------------------------------------------------===//
def cl_ext_EQ : CommaJoined<["-"], "cl-ext=">,
HelpText<"OpenCL only. Enable or disable OpenCL extensions. The argument is a comma-separated sequence of one or more extension names, each prefixed by '+' or '-'.">;
//===----------------------------------------------------------------------===//
// CUDA Options
//===----------------------------------------------------------------------===//

View File

@ -8799,6 +8799,7 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
return nullptr;
Target->setSupportedOpenCLOpts();
Target->setOpenCLExtensionOpts();
if (!Target->validateTarget(Diags))
return nullptr;

View File

@ -2385,6 +2385,7 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
// Use the default target triple if unspecified.
if (Opts.Triple.empty())
Opts.Triple = llvm::sys::getDefaultTargetTriple();
Opts.OpenCLExtensionsAsWritten = Args.getAllArgValues(OPT_cl_ext_EQ);
}
bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,

View File

@ -2,7 +2,26 @@
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL1.1
// Test with a target not supporting fp64.
// RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -DNOFP64
// RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -DNOFP64 -DNOFP16
// Test with some extensions enabled or disabled by cmd-line args
//
// Target does not support fp64 and fp16 - override it
// RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=+cl_khr_fp64,+cl_khr_fp16
//
// Disable or enable all extensions
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-all -DNOFP64 -DNOFP16
// RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=+all
// RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=+all,-cl_khr_fp64 -DNOFP64
// RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=-all,+cl_khr_fp64 -DNOFP16
//
// Concatenating
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-cl_khr_fp64 -cl-ext=+cl_khr_fp64
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-cl_khr_fp64,+cl_khr_fp64
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-all -cl-ext=+cl_khr_fp64 -cl-ext=+cl_khr_fp16 -cl-ext=-cl_khr_fp64 -DNOFP64
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-all -cl-ext=+cl_khr_fp64,-cl_khr_fp64,+cl_khr_fp16 -DNOFP64
void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 extension}}
double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}}
@ -14,6 +33,11 @@ void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 exte
// expected-warning@-2{{unsupported OpenCL extension 'cl_khr_fp64' - ignoring}}
#endif
#pragma OPENCL EXTENSION cl_khr_fp16 : enable
#ifdef NOFP16
// expected-warning@-2{{unsupported OpenCL extension 'cl_khr_fp16' - ignoring}}
#endif
void f2(void) {
double d;
#ifdef NOFP64