diff --git a/clang/include/clang/DPCT/DPCTOptions.inc b/clang/include/clang/DPCT/DPCTOptions.inc new file mode 100644 index 000000000000..f720b3eedf33 --- /dev/null +++ b/clang/include/clang/DPCT/DPCTOptions.inc @@ -0,0 +1,388 @@ +#ifndef DPCT_OPT_TYPE +#define DPCT_OPT_TYPE(...) +#endif +#ifndef DPCT_OPT_ENUM +#define DPCT_OPT_ENUM(NAME, ...) +#endif +#ifndef DPCT_OPTION_VALUES +#define DPCT_OPTION_VALUES(...) +#endif +#ifndef DPCT_NON_ENUM_OPTION +#define DPCT_NON_ENUM_OPTION(OPT_TYPE, OPT_VAR, OPTION_NAME, ...) +#endif +#ifndef DPCT_ENUM_OPTION +#define DPCT_ENUM_OPTION(OPT_TYPE, OPT_VAR, OPTION_NAME, ...) +#endif + +#ifdef DPCT_OPTIONS_IN_CLANG_TOOLING +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), BuildPath, "p", + llvm::cl::desc("The directory path for the compilation database (compile_commands.json). When no\n" + "path is specified, a search for compile_commands.json is attempted through all\n" + "parent directories of the first input source file."), + llvm::cl::value_desc("dir"), llvm::cl::cat(Category), + llvm::cl::Optional, llvm::cl::sub(*llvm::cl::AllSubCommands)) +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::list), ArgsAfter, "extra-arg", + llvm::cl::desc("Additional argument to append to the migration command line, example:\n" + "--extra-arg=\"-I /path/to/header\". The options that can be passed this way can\n" + "be found with the dpct -- -help command."), + llvm::cl::value_desc("string"), llvm::cl::cat(Category), + llvm::cl::sub(*llvm::cl::AllSubCommands)) +#ifdef _WIN32 +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), VcxprojFile, "vcxprojfile", + llvm::cl::desc("The file path of vcxproj."), + llvm::cl::value_desc("file"), llvm::cl::cat(Category), + llvm::cl::Optional, llvm::cl::sub(*llvm::cl::AllSubCommands)) +#endif +#endif // !DPCT_OPTIONS_IN_CLANG_TOOLING + +#ifdef DPCT_OPTIONS_IN_CLANG_DPCT +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), InRoot, "in-root", + llvm::cl::desc("The directory path for the root of the source tree that needs " + "to be migrated.\n" + "Only files under this root are migrated. Default: Current" + " directory, if input\nsource files are not provided. " + "If input source files are provided, the directory\n" + "of the first input source file is used."), + llvm::cl::value_desc("dir"), llvm::cl::cat(DPCTCat), + llvm::cl::Optional) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), OutRoot, "out-root", + llvm::cl::desc("The directory path for root of generated files. A directory is " + "created if it\n" + "does not exist. Default: dpct_output."), + llvm::cl::value_desc("dir"), llvm::cl::cat(DPCTCat), + llvm::cl::Optional) +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), CudaIncludePath, "cuda-include-path", + llvm::cl::desc("The directory path of the CUDA header files."), + llvm::cl::value_desc("dir"), cat(DPCTCat), + llvm::cl::Optional) +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), ReportFilePrefix, "report-file-prefix", + llvm::cl::desc( + "Prefix for the report file names. The full file name will have a " + "suffix derived\n" + "from the report-type and an extension derived from the report-format. " + "For\n" + "example: .apis.csv or .stats.log. If this option is " + "not\n" + "specified, the report will go to stdout. The report files are created " + "in the\n" + "directory, specified by -out-root."), + llvm::cl::value_desc("prefix"), llvm::cl::cat(DPCTCat), + llvm::cl::Optional) +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), ReportOnly, "report-only", + llvm::cl::desc("Only reports are generated. No SYCL code is " + "generated. Default: off."), + llvm::cl::cat(DPCTCat), llvm::cl::location(ReportOnlyFlag)) +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), ShowOrigCode, "keep-original-code", + llvm::cl::desc("Keeps the original code in comments of " + "generated SYCL files. Default: off.\n"), + llvm::cl::cat(DPCTCat), llvm::cl::location(KeepOriginalCodeFlag)) + +#ifdef DPCT_DEBUG_BUILD +DPCT_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), ReportType, "report-type", + DPCT_OPTION_VALUES( + DPCT_OPT_ENUM("apis", int(ReportTypeEnum::RTE_APIs), + "Information about API signatures that need migration and the number of times\n" + "they were encountered. The report file name will have .apis suffix added.", false), + DPCT_OPT_ENUM("stats", int(ReportTypeEnum::RTE_Stats), + "High level migration statistics: Lines Of Code (LOC) that are migrated to\n" + "SYCL, LOC migrated to SYCL with helper functions, LOC not needing migration,\n" + "LOC needing migration but are not migrated. The report file name has the .stats\n" + "suffix added (default)", false), + DPCT_OPT_ENUM("all", int(ReportTypeEnum::RTE_All), + "All of the reports.", false), + DPCT_OPT_ENUM("diags", int(ReportTypeEnum::RTE_Diags), + "diags information", true) + ), + llvm::cl::desc("Specifies the type of report. Values are:\n"), + llvm::cl::init(ReportTypeEnum::RTE_NotSetType), llvm::cl::value_desc("value"), llvm::cl::cat(DPCTCat), + llvm::cl::Optional) +#else +DPCT_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), ReportType, "report-type", + DPCT_OPTION_VALUES( + DPCT_OPT_ENUM("apis", int(ReportTypeEnum::RTE_APIs), + "Information about API signatures that need migration and the number of times\n" + "they were encountered. The report file name will have .apis suffix added.", false), + DPCT_OPT_ENUM("stats", int(ReportTypeEnum::RTE_Stats), + "High level migration statistics: Lines Of Code (LOC) that are migrated to\n" + "SYCL, LOC migrated to SYCL with helper functions, LOC not needing migration,\n" + "LOC needing migration but are not migrated. The report file name has the .stats\n" + "suffix added (default)", false), + DPCT_OPT_ENUM("all", int(ReportTypeEnum::RTE_All), + "All of the reports.", false) + ), + llvm::cl::desc("Specifies the type of report. Values are:\n"), + llvm::cl::init(ReportTypeEnum::RTE_NotSetType), llvm::cl::value_desc("value"), llvm::cl::cat(DPCTCat), + llvm::cl::Optional) +#endif + +DPCT_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), ReportFormat, "report-format", + DPCT_OPTION_VALUES( + DPCT_OPT_ENUM("csv", int(ReportFormatEnum::RFE_CSV), + "Output is lines of comma separated values. The report file " + "name extension will\n" + "be .csv. (default)", false), + DPCT_OPT_ENUM("formatted", int(ReportFormatEnum::RFE_Formatted), + "Output is formatted to be easier to read for " + "human eyes. Report file name\n" + "extension will be log.", + false) + ), + llvm::cl::desc("Format of the reports:\n"), + llvm::cl::init(ReportFormatEnum::RFE_NotSetFormat), llvm::cl::value_desc("value"), llvm::cl::cat(DPCTCat), + llvm::cl::Optional) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(llvm::cl::opt), SuppressWarnings, "suppress-warnings", + llvm::cl::desc(SuppressWarningsMessage), + llvm::cl::value_desc("value"), llvm::cl::cat(DPCTCat)) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), SuppressWarningsAll, "suppress-warnings-all", + llvm::cl::desc("Suppresses all migration warnings. Default: off."), + llvm::cl::cat(DPCTCat), llvm::cl::location(SuppressWarningsAllFlag)) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), StopOnParseErrOption, "stop-on-parse-err", + llvm::cl::desc("Stop migration and generation of reports if " + "parsing errors happened. Default: off. \n"), + llvm::cl::cat(DPCTCat), llvm::cl::location(StopOnParseErr)) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), CheckUnicodeSecurity, "check-unicode-security", + llvm::cl::desc("Enable detection and warnings about Unicode constructs that can be exploited by using\n" + "bi-directional formatting codes and homoglyphs in identifiers. Default: off.\n"), + llvm::cl::cat(DPCTCat), llvm::cl::location(CheckUnicodeSecurityFlag)) +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), SyclNamedLambda, "sycl-named-lambda", + llvm::cl::desc("Generates kernels with the kernel name. Default: off.\n"), + llvm::cl::cat(DPCTCat), llvm::cl::location(SyclNamedLambdaFlag)) + +DPCT_ENUM_OPTION(DPCT_OPT_TYPE(llvm::cl::opt), OutputVerbosity, "output-verbosity", + DPCT_OPTION_VALUES( + DPCT_OPT_ENUM("silent", int(OutputVerbosityLevel::OVL_Silent), + "Only messages from clang.", false), + DPCT_OPT_ENUM("normal", int(OutputVerbosityLevel::OVL_Normal), + "\'silent\' and warnings, errors, and notes from dpct.", + false), + DPCT_OPT_ENUM("detailed", int(OutputVerbosityLevel::OVL_Detailed), + "\'normal\' and messages about which file is being processed.", + false), + DPCT_OPT_ENUM("diagnostics", int(OutputVerbosityLevel::OVL_Diagnostics), + "\'detailed\' and information about the detected " + "conflicts and crashes. (default)", false) + ), + llvm::cl::desc("Sets the output verbosity level:"), + llvm::cl::init(OutputVerbosityLevel::OVL_Diagnostics), llvm::cl::value_desc("value"), llvm::cl::cat(DPCTCat), + llvm::cl::Optional) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(llvm::cl::opt), OutputFile, "output-file", + llvm::cl::desc("Redirects the stdout/stderr output to in the output" + " directory specified\n" + "by the --out-root option."), + llvm::cl::value_desc("file"), llvm::cl::cat(DPCTCat), llvm::cl::Optional) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::list), RuleFile, "rule-file", + llvm::cl::desc("Specifies the rule file path that contains rules used for migration.\n"), + llvm::cl::value_desc("file"), llvm::cl::cat(DPCTCat), llvm::cl::ZeroOrMore) + +DPCT_ENUM_OPTION(DPCT_OPT_TYPE(llvm::cl::opt), USMLevel, "usm-level", + DPCT_OPTION_VALUES( + DPCT_OPT_ENUM("restricted", int(UsmLevel::UL_Restricted), + "Uses USM API for memory management migration. (default)", false), + DPCT_OPT_ENUM("none", int(UsmLevel::UL_None), + "Uses helper functions from DPCT header files for memory " + "management migration.", false) + ), + llvm::cl::desc("Sets the Unified Shared Memory (USM) level to use in source code generation.\n"), + llvm::cl::init(UsmLevel::UL_Restricted), llvm::cl::value_desc("value"), llvm::cl::cat(DPCTCat), + llvm::cl::Optional) + +DPCT_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), FormatRng, "format-range", + DPCT_OPTION_VALUES( + DPCT_OPT_ENUM("migrated", int(format::FormatRange::migrated), + "Only formats the migrated code (default).", false), + DPCT_OPT_ENUM("all", int(format::FormatRange::all), + "Formats all code.", false), + DPCT_OPT_ENUM("none", int(format::FormatRange::none), + "Do not format any code.", false) + ), + llvm::cl::desc("Sets the range of formatting.\nThe values are:\n"), + llvm::cl::init(format::FormatRange::migrated), llvm::cl::value_desc("value"), llvm::cl::cat(DPCTCat), + llvm::cl::Optional) +DPCT_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), FormatST, "format-style", + DPCT_OPTION_VALUES( + DPCT_OPT_ENUM("llvm", int(DPCTFormatStyle::FS_LLVM), + "Use the LLVM coding style.", false), + DPCT_OPT_ENUM("google", int(DPCTFormatStyle::FS_Google), + "Use the Google coding style.", false), + DPCT_OPT_ENUM("custom", int(DPCTFormatStyle::FS_Custom), + "Use the coding style defined in the .clang-format file (default).", false) + ), + llvm::cl::desc("Sets the formatting style.\nThe values are:\n"), + llvm::cl::init(DPCTFormatStyle::FS_Custom), llvm::cl::value_desc("value"), llvm::cl::cat(DPCTCat), + llvm::cl::Optional) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), NoClNamespaceInline, "no-cl-namespace-inline", + llvm::cl::desc("DEPRECATED: Do not use cl:: namespace inline. Default: off. This option will be\n" + "ignored if the replacement option --use-explicit-namespace is used.\n"), + llvm::cl::cat(DPCTCat), llvm::cl::location(ExplicitClNamespace)) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), NoDRYPattern, "no-dry-pattern", + llvm::cl::desc("Do not use DRY (do not repeat yourself) pattern when functions from dpct\n" + "namespace are inserted. Default: off.\n"), + llvm::cl::cat(DPCTCat), llvm::cl::location(NoDRYPatternFlag)) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), ProcessAll, "process-all", + llvm::cl::desc("Migrates or copies all files, except hidden, from the --in-root directory\n" + "to the --out-root directory. The --in-root option should be explicitly specified.\n" + "Default: off."), + llvm::cl::cat(DPCTCat), llvm::cl::location(ProcessAllFlag)) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), EnableCTAD, "enable-ctad", + llvm::cl::desc("Use a C++17 class template argument deduction (CTAD) in " + "your generated code.\n" + "Default: off."), + llvm::cl::cat(DPCTCat), llvm::cl::init(false)) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), EnableComments, "comments", + llvm::cl::desc("Insert comments explaining the generated code. Default: off."), + llvm::cl::cat(DPCTCat), llvm::cl::init(false)) + +DPCT_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), UseCustomHelperFileLevel, "use-custom-helper", + DPCT_OPTION_VALUES( + DPCT_OPT_ENUM("none", int(HelperFilesCustomizationLevel::HFCL_None), + "No customization (default).", false), + DPCT_OPT_ENUM("file", int(HelperFilesCustomizationLevel::HFCL_File), + "Limit helper header files to only the necessary files for the migrated code and\n" + "place them in the --out-root directory.", false), + DPCT_OPT_ENUM("api", int(HelperFilesCustomizationLevel::HFCL_API), + "Limit helper header files to only the necessary APIs for the migrated code and\n" + "place them in the --out-root directory.", false), + DPCT_OPT_ENUM("all", int(HelperFilesCustomizationLevel::HFCL_All), + "Generate a complete set of helper header files and place them in the --out-root\n" + "directory.", false) + ), + llvm::cl::desc("Customize the helper header files for migrated code. The values are:\n"), + llvm::cl::init(HelperFilesCustomizationLevel::HFCL_None), llvm::cl::value_desc("value"), llvm::cl::cat(DPCTCat), + llvm::cl::Optional) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), CustomHelperFileName, "custom-helper-name", + llvm::cl::desc("Specifies the helper headers folder name and main helper header file name.\n" + "Default: dpct."), + llvm::cl::init("dpct"), llvm::cl::value_desc("name"), llvm::cl::cat(DPCTCat), llvm::cl::Optional) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), AsyncHandler, "always-use-async-handler", + llvm::cl::desc("Use async exception handler when creating new sycl::queue " + "with dpct::create_queue\nin addition to default " + "dpct::get_default_queue. Default: off."), + llvm::cl::cat(DPCTCat), llvm::cl::location(AsyncHandlerFlag)) + +DPCT_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), NDRangeDim, "assume-nd-range-dim", + DPCT_OPTION_VALUES( + DPCT_OPT_ENUM("1", 1, + "Generate kernel code assuming 1D nd_range " + "where possible, and 3D in other cases.", + false), + DPCT_OPT_ENUM("3", 3, + "Generate kernel code assuming 3D nd_range (default).", + false) + ), + llvm::cl::desc("Provides a hint to the tool on the dimensionality of nd_range to use in generated code.\n" + "The values are:\n"), + llvm::cl::init(AssumedNDRangeDimEnum::ARE_Dim3), llvm::cl::value_desc("value"), llvm::cl::cat(DPCTCat), + llvm::cl::Optional) + +DPCT_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::list), UseExplicitNamespace, "use-explicit-namespace", + DPCT_OPTION_VALUES( + DPCT_OPT_ENUM("none", int(ExplicitNamespace::EN_None), + "Generate code without namespaces. Cannot " + "be used with other values.", + false), + DPCT_OPT_ENUM("cl", int(ExplicitNamespace::EN_CL), + "Generate code with cl::sycl:: namespace. Cannot be used with " + "sycl or sycl-math values.", + false), + DPCT_OPT_ENUM("dpct", int(ExplicitNamespace::EN_DPCT), + "Generate code with dpct:: namespace.", + false), + DPCT_OPT_ENUM("sycl", int(ExplicitNamespace::EN_SYCL), + "Generate code with sycl:: namespace. Cannot be used with cl or " + "sycl-math values.", + false), + DPCT_OPT_ENUM("sycl-math", int(ExplicitNamespace::EN_SYCL_Math), + "Generate code with sycl:: namespace, applied only for SYCL math functions.\n" + "Cannot be used with cl or sycl values.", + false) + ), + llvm::cl::desc("Defines the namespaces to use explicitly in generated code. The value is a comma\n" + "separated list. Default: dpct, sycl.\n" + "Possible values are:"), + llvm::cl::CommaSeparated, llvm::cl::value_desc("value"), llvm::cl::cat(DPCTCat), llvm::cl::ZeroOrMore) + +// When more dpcpp extensions are implemented, more extension names will be +// added into the value of option --no-dpcpp-extensions, currently only +// Enqueued barriers is supported. +DPCT_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::list), NoDPCPPExtensions, "no-dpcpp-extensions", + DPCT_OPTION_VALUES( + DPCT_OPT_ENUM("enqueued_barriers", + int(DPCPPExtensions::Ext_EnqueueBarrier), + "Enqueued barriers extension.", + false) + ), + llvm::cl::desc("Comma separated list of extensions not to be used in migrated " + "code.\n" + "By default, these extensions will be used in migrated code."), + llvm::cl::CommaSeparated, llvm::cl::value_desc("value"), llvm::cl::cat(DPCTCat), llvm::cl::ZeroOrMore, + llvm::cl::cb(DpctGlobalInfo::setExtensionUnused)) + +DPCT_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::bits), Experimentals, "use-experimental-features", + DPCT_OPTION_VALUES( + DPCT_OPT_ENUM("free-function-queries", int(ExperimentalFeatures::Exp_FreeQueries), + "Experimental extension that allows getting `id`, `item`, `nd_item`, `group`, and\n" + "`sub_group` instances globally.", + false), + DPCT_OPT_ENUM("local-memory-kernel-scope-allocation", int(ExperimentalFeatures::Exp_GroupSharedMemory), + "Experimental extension that allows allocation of local memory objects at the kernel\n" + "functor scope", + false), + DPCT_OPT_ENUM("logical-group", int(ExperimentalFeatures::Exp_LogicalGroup), + "Experimental helper function used to logically group work-items.", + false), + DPCT_OPT_ENUM("nd_range_barrier", int(ExperimentalFeatures::Exp_NdRangeBarrier), + "Experimental helper function used to help cross group synchronization during migration.\n", + false) + ), + llvm::cl::desc("Comma separated list of experimental features to be used in migrated " + "code.\n" + "By default, experimental features will not be used in migrated code.\nThe values are:\n"), + llvm::cl::CommaSeparated, llvm::cl::value_desc("value"), llvm::cl::cat(DPCTCat), llvm::cl::ZeroOrMore) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(llvm::cl::opt), GenBuildScript, "gen-build-script", + llvm::cl::desc("Generates makefile for migrated file(s) in -out-root directory. Default: off."), + llvm::cl::cat(DPCTCat), llvm::cl::init(false)) +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(llvm::cl::opt), BuildScriptFile, "build-script-file", + llvm::cl::desc("Specifies the name of generated makefile for migrated file(s).\n" + "Default name: Makefile.dpct."), + llvm::cl::value_desc("file"), llvm::cl::cat(DPCTCat), llvm::cl::Optional) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::list), ExcludePathList, "in-root-exclude", + llvm::cl::desc("Excludes the specified directory or file from processing."), + llvm::cl::value_desc("dir|file"), llvm::cl::cat(DPCTCat), llvm::cl::ZeroOrMore) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), OptimizeMigration, "optimize-migration", + llvm::cl::desc("Generates SYCL code applying more aggressive assumptions that potentially\n" + "may alter the semantics of your program. Default: off."), + llvm::cl::cat(DPCTCat), llvm::cl::init(false)) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), NoIncrementalMigration, "no-incremental-migration", + llvm::cl::desc("Tells the tool to not perform an incremental migration.\n" + "Default: off (incremental migration happens)."), + llvm::cl::cat(DPCTCat), llvm::cl::init(false)) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), QueryApiMapping, "query-api-mapping", + llvm::cl::desc("Provides functionally compatible SYCL API mapping for CUDA API."), + llvm::cl::value_desc("api"), llvm::cl::cat(DPCTCat), llvm::cl::Optional) + +DPCT_NON_ENUM_OPTION(DPCT_OPT_TYPE(static llvm::cl::opt), AnalysisScope, "analysis-scope-path", + llvm::cl::desc("The directory path for the analysis scope of the source tree that " + "needs to be migrated.\n" + "Default: the value of --in-root"), + llvm::cl::value_desc("dir"), llvm::cl::cat(DPCTCat)) + +#endif // !DPCT_OPTIONS_IN_CLANG_DPCT diff --git a/clang/lib/DPCT/AutoComplete.cpp b/clang/lib/DPCT/AutoComplete.cpp new file mode 100644 index 000000000000..a5848ae27c66 --- /dev/null +++ b/clang/lib/DPCT/AutoComplete.cpp @@ -0,0 +1,166 @@ +//===--------------- AutoComplete.cpp -------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "AutoComplete.h" +#include "Error.h" +#include "Utility.h" +#include "llvm/Support/raw_ostream.h" +#include + +namespace clang { +namespace dpct { + +static std::map> DPCTOptionInfoMap = { + // To avoid make llvm library depends on this file, hard code 2 options here. + {"help", {}}, + {"version", {}}, +#define DPCT_OPTIONS_IN_LLVM_SUPPORT +#define DPCT_OPTIONS_IN_CLANG_TOOLING +#define DPCT_OPTIONS_IN_CLANG_DPCT + +#define DPCT_OPT_TYPE(...) 0 +#define DPCT_OPT_ENUM(NAME, ...) NAME +#define DPCT_OPTION_VALUES(...) \ + { __VA_ARGS__ } +#define DPCT_NON_ENUM_OPTION(OPT_TYPE, OPT_VAR, OPTION_NAME, ...) \ + {OPTION_NAME, {}}, +#define DPCT_ENUM_OPTION(OPT_TYPE, OPT_VAR, OPTION_NAME, OPTION_VALUES, ...) \ + {OPTION_NAME, OPTION_VALUES}, + +#include "clang/DPCT/DPCTOptions.inc" + +#undef DPCT_ENUM_OPTION +#undef DPCT_NON_ENUM_OPTION +#undef DPCT_OPT_ENUM +#undef DPCT_OPT_TYPE + +#undef DPCT_OPTIONS_IN_CLANG_DPCT +#undef DPCT_OPTIONS_IN_CLANG_TOOLING +#undef DPCT_OPTIONS_IN_LLVM_SUPPORT +}; + +void AutoCompletePrinter::process() { + llvm::StringRef InputRef(Input); + LastSharpPos = InputRef.find_last_of('#'); + if (LastSharpPos == (InputRef.size() - 1)) { + // No char after last '#', it means user press tab after a space, + // return empty line to show files/folders + printAndExit(); + } + + bool SuggestEnumValue = + (InputRef.find("=", LastSharpPos) != llvm::StringRef::npos) || + (LastSharpPos >= 1 && InputRef[LastSharpPos - 1] == '='); + if (!SuggestEnumValue) { + // suggest option names + llvm::StringRef OptionPrefixRef = InputRef.substr(LastSharpPos + 1); + + // Case0: "" : return empty. + // Case1: "-" : suggest all options. All candidates have "--" prefix except "-p". + // Case2: "--" : suggest all options except -p. All candidates have "--" prefix. + // Case3: "-abc" : suggest options have abc prefix. All candidates have "-" prefix. + // Case4: "--abc" : suggest options have abc prefix. All candidates have "--" prefix. + + if (OptionPrefixRef.size() == 0) { + // Case0 + printAndExit(); + } else if (OptionPrefixRef.size() == 1 && OptionPrefixRef[0] == '-') { + // Case1 + addSuggestions(OptionSet, false); + printAndExit(); + } else if (OptionPrefixRef.size() == 2 && OptionPrefixRef[0] == '-' && + OptionPrefixRef[1] == '-') { + // Case2 + addSuggestions(OptionSet, true); + printAndExit(); + } else if (OptionPrefixRef.size() >= 2 && OptionPrefixRef[0] == '-' && + OptionPrefixRef[1] != '-') { + // Case3 + addSuggestions(OptionSet, OptionPrefixRef.substr(1), "-"); + printAndExit(); + } else if (OptionPrefixRef.size() >= 3 && OptionPrefixRef[0] == '-' && + OptionPrefixRef[1] == '-') { + // Case4 + addSuggestions(OptionSet, OptionPrefixRef.substr(2), "--"); + printAndExit(); + } + printAndExit(); + } + + // suggest enum values + // E.g., "--foobar=abc,def,g" + // CurOptionNameRef is "foobar=" + // EnumPrefixRef is "g" + // ResultPrefixRef is "abc,def," + llvm::StringRef CurOptionNameRef; + llvm::StringRef EnumPrefixRef; + llvm::StringRef ResultPrefixRef; + + auto EqualPos = InputRef.find("=", LastSharpPos); + if (EqualPos != llvm::StringRef::npos) { + // InputRef: #--foo= + auto OptionNameStartPos = InputRef.find_first_not_of('-', LastSharpPos + 1); + CurOptionNameRef = InputRef.substr(OptionNameStartPos, + InputRef.size() - OptionNameStartPos); + addSuggestions(OptionEnumsMap[CurOptionNameRef.str()], "", ""); + printAndExit(); + } + // InputRef: #--foo=#... + auto SharpPosBeforeLastSharp = + InputRef.substr(0, LastSharpPos).find_last_of('#'); + auto OptionNameStartPos = + InputRef.find_first_not_of('-', SharpPosBeforeLastSharp + 1); + CurOptionNameRef = + InputRef.substr(OptionNameStartPos, LastSharpPos - OptionNameStartPos); + auto StrAfterLastSharp = InputRef.substr(LastSharpPos + 1); + auto LastCommaPosAfterLastSharp = StrAfterLastSharp.find_last_of(','); + if (LastCommaPosAfterLastSharp != llvm::StringRef::npos) { + // InputRef: #--foo=#abc,def,g + EnumPrefixRef = StrAfterLastSharp.substr(LastCommaPosAfterLastSharp + 1); + ResultPrefixRef = + StrAfterLastSharp.substr(0, LastCommaPosAfterLastSharp + 1); + addSuggestions(OptionEnumsMap[CurOptionNameRef.str()], EnumPrefixRef, ResultPrefixRef); + printAndExit(); + } else { + // InputRef: #--foo=#ab + EnumPrefixRef = StrAfterLastSharp; + addSuggestions(OptionEnumsMap[CurOptionNameRef.str()], EnumPrefixRef, ""); + printAndExit(); + } +} + +void AutoCompletePrinter::operator=(std::string RawInput) { + for (const auto &I : DPCTOptionInfoMap) { + if (I.second.empty()) { + OptionSet.insert(I.first); + } else { + const std::string Key = I.first + "="; + OptionSet.insert(Key); + for (const auto &Enum : I.second) { + OptionEnumsMap[Key].insert(Enum); + } + } + } + Input = "#" + RawInput; + process(); +} + +void AutoCompletePrinter::printAndExit() { + if (Suggestions.empty()) { + llvm::outs() << "\n"; + dpctExit(MigrationSucceeded); + } + + for (const auto &Opt : Suggestions) { + llvm::outs() << Opt << "\n"; + } + dpctExit(MigrationSucceeded); +} + +} // namespace dpct +} diff --git a/clang/lib/DPCT/AutoComplete.h b/clang/lib/DPCT/AutoComplete.h new file mode 100644 index 000000000000..56ce503fdf14 --- /dev/null +++ b/clang/lib/DPCT/AutoComplete.h @@ -0,0 +1,56 @@ +//===--------------- AutoComplete.h ---------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef DPCT_AUTOCOMPLETE_H +#define DPCT_AUTOCOMPLETE_H + +#include "llvm/ADT/StringRef.h" +#include +#include +#include +#include +#include + +namespace clang { +namespace dpct { +class AutoCompletePrinter { + std::set Suggestions; + std::set OptionSet; + std::map> OptionEnumsMap; + std::string Input; + void printAndExit(); + void process(); + std::string::size_type LastSharpPos; + void addSuggestions(const std::set& Set, + const llvm::StringRef Prefix, + const llvm::StringRef ResultPrefix) { + for (const auto &Item : Set) { + llvm::StringRef ItemRef(Item); + if (ItemRef.startswith(Prefix)) { + Suggestions.insert(ResultPrefix.str() + Item); + } + } + } + void addSuggestions(const std::set& Set, + bool MustBeginWithDashDash) { + for (const auto &Opt : OptionSet) { + if (Opt.size() == 1 && !MustBeginWithDashDash) { + Suggestions.insert("-" + Opt); + } else { + Suggestions.insert("--" + Opt); + } + } + } +public: + AutoCompletePrinter() {} + void operator=(std::string RawInput); +}; +} +} + +#endif diff --git a/clang/lib/DPCT/DPCT.cpp b/clang/lib/DPCT/DPCT.cpp index a3e7275cb5ac..0e8be7a0e6b6 100644 --- a/clang/lib/DPCT/DPCT.cpp +++ b/clang/lib/DPCT/DPCT.cpp @@ -9,6 +9,7 @@ #include "clang/DPCT/DPCT.h" #include "ASTTraversal.h" #include "AnalysisInfo.h" +#include "AutoComplete.h" #include "CallExprRewriter.h" #include "TypeLocRewriters.h" #include "Checkpoint.h" @@ -109,410 +110,72 @@ const char *const CtHelpHint = "\n"; static extrahelp CommonHelp(CtHelpMessage); -static opt Passes( - "passes", - desc("Comma separated list of migration passes, which will be applied.\n" - "Only the specified passes are applied."), - value_desc("IterationSpaceBuiltinRule,..."), cat(DPCTCat), - llvm::cl::Hidden); -static opt - InRoot("in-root", - desc("The directory path for the root of the source tree that needs " - "to be migrated.\n" - "Only files under this root are migrated. Default: Current" - " directory, if input\nsource files are not provided. " - "If input source files are provided, the directory\n" - "of the first input source file is used."), - value_desc("dir"), cat(DPCTCat), - llvm::cl::Optional); -static opt - AnalysisScope("analysis-scope-path", - desc("The directory path for the analysis scope of the source tree that " - "needs to be migrated.\n" - "Default: the value of --in-root"), - value_desc("dir"), cat(DPCTCat)); -static opt OutRoot( - "out-root", - desc("The directory path for root of generated files. A directory is " - "created if it\n" - "does not exist. Default: dpct_output."), - value_desc("dir"), cat(DPCTCat), llvm::cl::Optional); - -static opt SDKPath("cuda-path", desc("Directory path of SDK.\n"), - value_desc("dir"), cat(DPCTCat), - llvm::cl::Optional, llvm::cl::Hidden); -static opt - CudaIncludePath("cuda-include-path", - desc("The directory path of the CUDA header files."), - value_desc("dir"), cat(DPCTCat), llvm::cl::Optional); - -static opt ReportType( - "report-type", desc("Specifies the type of report. Values are:\n"), - llvm::cl::values( - llvm::cl::OptionEnumValue{"apis", int(ReportTypeEnum::RTE_APIs), - "Information about API signatures that need migration and the number of times\n" - "they were encountered. The report file name will have .apis suffix added.", false}, - llvm::cl::OptionEnumValue{"stats", int(ReportTypeEnum::RTE_Stats), - "High level migration statistics: Lines Of Code (LOC) that are migrated to\n" - "SYCL, LOC migrated to SYCL with helper functions, LOC not needing migration,\n" - "LOC needing migration but are not migrated. The report file name has the .stats\n" - "suffix added (default)", false}, - llvm::cl::OptionEnumValue{"all", int(ReportTypeEnum::RTE_All), - "All of the reports.", false} - #ifdef DPCT_DEBUG_BUILD - , llvm::cl::OptionEnumValue{"diags", int(ReportTypeEnum::RTE_Diags), - "diags information", true} - #endif - ), - llvm::cl::init(ReportTypeEnum::RTE_NotSetType), value_desc("value"), cat(DPCTCat), - llvm::cl::Optional); - -static opt ReportFormat( - "report-format", desc("Format of the reports:\n"), - llvm::cl::values( - llvm::cl::OptionEnumValue{"csv", int(ReportFormatEnum::RFE_CSV), - "Output is lines of comma separated values. The report file " - "name extension will\n" - "be .csv. (default)", false}, - llvm::cl::OptionEnumValue{"formatted", int(ReportFormatEnum::RFE_Formatted), - "Output is formatted to be easier to read for " - "human eyes. Report file name\n" - "extension will be log.", - false}), - llvm::cl::init(ReportFormatEnum::RFE_NotSetFormat), value_desc("value"), cat(DPCTCat), - llvm::cl::Optional); - -static opt ReportFilePrefix( - "report-file-prefix", - desc( - "Prefix for the report file names. The full file name will have a " - "suffix derived\n" - "from the report-type and an extension derived from the report-format. " - "For\n" - "example: .apis.csv or .stats.log. If this option is " - "not\n" - "specified, the report will go to stdout. The report files are created " - "in the\n" - "directory, specified by -out-root."), - value_desc("prefix"), cat(DPCTCat), llvm::cl::Optional); bool ReportOnlyFlag = false; -static opt - ReportOnly("report-only", - llvm::cl::desc("Only reports are generated. No SYCL code is " - "generated. Default: off."), - cat(DPCTCat), llvm::cl::location(ReportOnlyFlag)); - bool KeepOriginalCodeFlag = false; - -static opt - ShowOrigCode("keep-original-code", - llvm::cl::desc("Keeps the original code in comments of " - "generated SYCL files. Default: off.\n"), - cat(DPCTCat), llvm::cl::location(KeepOriginalCodeFlag)); -#ifdef DPCT_DEBUG_BUILD -static opt - DiagsContent("report-diags-content", - desc("Diagnostics verbosity level. \"pass\": Basic migration " - "pass information. " - "\"transformation\": Detailed migration pass " - "transformation information."), - value_desc("[pass|transformation]"), cat(DPCTCat), - llvm::cl::Optional, llvm::cl::Hidden); -#endif -static std::string - WarningDesc("Comma separated list of migration warnings to suppress. Valid " - "warning IDs range\n" - "from " + std::to_string((size_t)Warnings::BEGIN) + " to " + - std::to_string((size_t)Warnings::END - 1) + - ". Hyphen separated ranges are also allowed. For example:\n" - "--suppress-warnings=1000-1010,1011."); -opt SuppressWarnings("suppress-warnings", desc(WarningDesc), - value_desc("value"), cat(DPCTCat)); - bool SuppressWarningsAllFlag = false; -static std::string WarningAllDesc("Suppresses all migration warnings. Default: off."); -opt SuppressWarningsAll("suppress-warnings-all", - desc(WarningAllDesc), cat(DPCTCat), - location(SuppressWarningsAllFlag)); bool StopOnParseErr = false; -static opt - StopOnParseErrOption("stop-on-parse-err", - llvm::cl::desc("Stop migration and generation of reports if " - "parsing errors happened. Default: off. \n"), - cat(DPCTCat), llvm::cl::location(StopOnParseErr)); - bool CheckUnicodeSecurityFlag = false; -static opt CheckUnicodeSecurity( - "check-unicode-security", - llvm::cl::desc("Enable detection and warnings about Unicode constructs that can be exploited by using\n" - "bi-directional formatting codes and homoglyphs in identifiers. Default: off.\n"), - cat(DPCTCat), llvm::cl::location(CheckUnicodeSecurityFlag)); - bool SyclNamedLambdaFlag = false; -static opt - SyclNamedLambda("sycl-named-lambda", - llvm::cl::desc("Generates kernels with the kernel name. Default: off.\n"), - cat(DPCTCat), llvm::cl::location(SyclNamedLambdaFlag)); - -opt OutputVerbosity( - "output-verbosity", llvm::cl::desc("Sets the output verbosity level:"), - llvm::cl::values( - llvm::cl::OptionEnumValue{"silent", int(OutputVerbosityLevel::OVL_Silent), - "Only messages from clang.", false}, - llvm::cl::OptionEnumValue{"normal", int(OutputVerbosityLevel::OVL_Normal), - "\'silent\' and warnings, errors, and notes from dpct.", - false}, - llvm::cl::OptionEnumValue{"detailed", int(OutputVerbosityLevel::OVL_Detailed), - "\'normal\' and messages about which file is being processed.", - false}, - llvm::cl::OptionEnumValue{"diagnostics", int(OutputVerbosityLevel::OVL_Diagnostics), - "\'detailed\' and information about the detected " - "conflicts and crashes. (default)", false}), - llvm::cl::init(OutputVerbosityLevel::OVL_Diagnostics), value_desc("value"), cat(DPCTCat), - llvm::cl::Optional); - -opt - OutputFile("output-file", - desc("Redirects the stdout/stderr output to in the output" - " directory specified\n" - "by the --out-root option."), - value_desc("file"), cat(DPCTCat), - llvm::cl::Optional); - -list RuleFile("rule-file", desc("Specifies the rule file path that contains rules used for migration.\n"), - value_desc("file"), cat(DPCTCat), llvm::cl::ZeroOrMore); - -opt USMLevel( - "usm-level", desc("Sets the Unified Shared Memory (USM) level to use in source code generation.\n"), - values(llvm::cl::OptionEnumValue{"restricted", int(UsmLevel::UL_Restricted), - "Uses USM API for memory management migration. (default)", false}, - llvm::cl::OptionEnumValue{"none", int(UsmLevel::UL_None), - "Uses helper functions from DPCT header files for memory " - "management migration.", false}), - init(UsmLevel::UL_Restricted), value_desc("value"), cat(DPCTCat), llvm::cl::Optional); - -opt - FormatRng("format-range", - llvm::cl::desc("Sets the range of formatting.\nThe values are:\n"), - values(llvm::cl::OptionEnumValue{"migrated", int(format::FormatRange::migrated), - "Only formats the migrated code (default).", false}, - llvm::cl::OptionEnumValue{"all", int(format::FormatRange::all), - "Formats all code.", false}, - llvm::cl::OptionEnumValue{"none", int(format::FormatRange::none), - "Do not format any code.", false}), - init(format::FormatRange::migrated), value_desc("value"), cat(DPCTCat), llvm::cl::Optional); - -opt - FormatST("format-style", - llvm::cl::desc("Sets the formatting style.\nThe values are:\n"), - values(llvm::cl::OptionEnumValue{"llvm", int(DPCTFormatStyle::FS_LLVM), - "Use the LLVM coding style.", false}, - llvm::cl::OptionEnumValue{"google", int(DPCTFormatStyle::FS_Google), - "Use the Google coding style.", false}, - llvm::cl::OptionEnumValue{"custom", int(DPCTFormatStyle::FS_Custom), - "Use the coding style defined in the .clang-format file (default).", false}), - init(DPCTFormatStyle::FS_Custom), value_desc("value"), cat(DPCTCat), llvm::cl::Optional); - bool ExplicitClNamespace = false; -static opt NoClNamespaceInline( - "no-cl-namespace-inline", - llvm::cl::desc("DEPRECATED: Do not use cl:: namespace inline. Default: off. This option will be\n" - "ignored if the replacement option --use-explicit-namespace is used.\n"), - cat(DPCTCat), llvm::cl::location(ExplicitClNamespace)); - bool NoDRYPatternFlag = false; -static opt NoDRYPattern( - "no-dry-pattern", llvm::cl::desc("Do not use DRY (do not repeat yourself) pattern when functions from dpct\n" - "namespace are inserted. Default: off.\n"), - cat(DPCTCat), llvm::cl::location(NoDRYPatternFlag)); - bool NoUseGenericSpaceFlag = false; -static opt NoUseGenericSpace( - "no-use-generic-space", llvm::cl::desc("sycl::access::address_space::generic_space is not used during atomic\n" - " function's migration. Default: off.\n"), - cat(DPCTCat), llvm::cl::location(NoUseGenericSpaceFlag), llvm::cl::ReallyHidden); - bool ProcessAllFlag = false; -static opt - ProcessAll("process-all", - llvm::cl::desc("Migrates or copies all files, except hidden, from the --in-root directory\n" - "to the --out-root directory. The --in-root option should be explicitly specified.\n" - "Default: off."), - cat(DPCTCat), llvm::cl::location(ProcessAllFlag)); - -static opt EnableCTAD( - "enable-ctad", - llvm::cl::desc("Use a C++17 class template argument deduction (CTAD) in " - "your generated code.\n" - "Default: off."), - cat(DPCTCat), init(false)); - -static opt EnableComments( - "comments", llvm::cl::desc("Insert comments explaining the generated code. Default: off."), - cat(DPCTCat), init(false)); - -static opt UseCustomHelperFileLevel( - "use-custom-helper", desc("Customize the helper header files for migrated code. The values are:\n"), - values( - llvm::cl::OptionEnumValue{ - "none", int(HelperFilesCustomizationLevel::HFCL_None), - "No customization (default).", false}, - llvm::cl::OptionEnumValue{ - "file", int(HelperFilesCustomizationLevel::HFCL_File), - "Limit helper header files to only the necessary files for the migrated code and\n" - "place them in the --out-root directory.", false}, - llvm::cl::OptionEnumValue{ - "api", int(HelperFilesCustomizationLevel::HFCL_API), - "Limit helper header files to only the necessary APIs for the migrated code and\n" - "place them in the --out-root directory.", false}, - llvm::cl::OptionEnumValue{ - "all", int(HelperFilesCustomizationLevel::HFCL_All), - "Generate a complete set of helper header files and place them in the --out-root\n" - "directory.", false}), - init(HelperFilesCustomizationLevel::HFCL_None), value_desc("value"), - cat(DPCTCat), llvm::cl::Optional); - -opt CustomHelperFileName( - "custom-helper-name", - desc( - "Specifies the helper headers folder name and main helper header file name.\n" - "Default: dpct."), - init("dpct"), value_desc("name"), cat(DPCTCat), llvm::cl::Optional); - bool AsyncHandlerFlag = false; -static opt AsyncHandler( - "always-use-async-handler", - llvm::cl::desc("Use async exception handler when creating new sycl::queue " - "with dpct::create_queue\nin addition to default " - "dpct::get_default_queue. Default: off."), - cat(DPCTCat), llvm::cl::location(AsyncHandlerFlag)); - -static opt NDRangeDim( - "assume-nd-range-dim", - desc("Provides a hint to the tool on the dimensionality of nd_range to use in generated code.\n" - "The values are:\n"), - values( - llvm::cl::OptionEnumValue{"1", 1, - "Generate kernel code assuming 1D nd_range " - "where possible, and 3D in other cases.", - false}, - llvm::cl::OptionEnumValue{ - "3", 3, - "Generate kernel code assuming 3D nd_range (default).", - false}), - init(AssumedNDRangeDimEnum::ARE_Dim3), value_desc("value"), cat(DPCTCat), - llvm::cl::Optional); - -static list UseExplicitNamespace( - "use-explicit-namespace", - llvm::cl::desc( - "Defines the namespaces to use explicitly in generated code. The value is a comma\n" - "separated list. Default: dpct, sycl.\n" - "Possible values are:"), - llvm::cl::CommaSeparated, - values(llvm::cl::OptionEnumValue{"none", int(ExplicitNamespace::EN_None), - "Generate code without namespaces. Cannot " - "be used with other values.", - false}, - llvm::cl::OptionEnumValue{ - "cl", int(ExplicitNamespace::EN_CL), - "Generate code with cl::sycl:: namespace. Cannot be used with " - "sycl or sycl-math values.", - false}, - llvm::cl::OptionEnumValue{"dpct", int(ExplicitNamespace::EN_DPCT), - "Generate code with dpct:: namespace.", - false}, - llvm::cl::OptionEnumValue{ - "sycl", int(ExplicitNamespace::EN_SYCL), - "Generate code with sycl:: namespace. Cannot be used with cl or " - "sycl-math values.", - false}, - llvm::cl::OptionEnumValue{ - "sycl-math", int(ExplicitNamespace::EN_SYCL_Math), - "Generate code with sycl:: namespace, applied only for SYCL math functions.\n" - "Cannot be used with cl or sycl values.", - false}), - value_desc("value"), cat(DPCTCat), llvm::cl::ZeroOrMore); - -// When more dpcpp extensions are implemented, more extension names will be -// added into the value of option --no-dpcpp-extensions, currently only -// Enqueued barriers is supported. -static list NoDPCPPExtensions( - "no-dpcpp-extensions", - llvm::cl::desc( - "Comma separated list of extensions not to be used in migrated " - "code.\n" - "By default, these extensions will be used in migrated code."), - llvm::cl::CommaSeparated, - values(llvm::cl::OptionEnumValue{"enqueued_barriers", - int(DPCPPExtensions::Ext_EnqueueBarrier), - "Enqueued barriers extension.", - false}), - value_desc("value"), cat(DPCTCat), llvm::cl::ZeroOrMore, - llvm::cl::cb(DpctGlobalInfo::setExtensionUnused)); - -static bits Experimentals( - "use-experimental-features", - llvm::cl::desc( - "Comma separated list of experimental features to be used in migrated " - "code.\n" - "By default, experimental features will not be used in migrated code.\nThe values are:\n"), - llvm::cl::CommaSeparated, - values( - llvm::cl::OptionEnumValue{ - "free-function-queries", int(ExperimentalFeatures::Exp_FreeQueries), - "Experimental extension that allows getting `id`, `item`, `nd_item`, `group`, and\n" - "`sub_group` instances globally.", - false }, - llvm::cl::OptionEnumValue{ - "local-memory-kernel-scope-allocation", int(ExperimentalFeatures::Exp_GroupSharedMemory), - "Experimental extension that allows allocation of local memory objects at the kernel\n" - "functor scope", - false }, - llvm::cl::OptionEnumValue{ - "logical-group", int(ExperimentalFeatures::Exp_LogicalGroup), - "Experimental helper function used to logically group work-items.", - false }, - llvm::cl::OptionEnumValue{ - "nd_range_barrier", int(ExperimentalFeatures::Exp_NdRangeBarrier), - "Experimental helper function used to help cross group synchronization during migration.\n", - false }), - value_desc("value"), cat(DPCTCat), llvm::cl::ZeroOrMore); - -opt GenBuildScript( - "gen-build-script", - llvm::cl::desc("Generates makefile for migrated file(s) in -out-root directory. Default: off."), - cat(DPCTCat), init(false)); - -opt - BuildScriptFile("build-script-file", - desc("Specifies the name of generated makefile for migrated file(s).\n" - "Default name: Makefile.dpct."), - value_desc("file"), cat(DPCTCat), - llvm::cl::Optional); - -static list ExcludePathList( - "in-root-exclude", - llvm::cl::desc( - "Excludes the specified directory or file from processing."), - value_desc("dir|file"), cat(DPCTCat), llvm::cl::ZeroOrMore); - -static opt OptimizeMigration( - "optimize-migration", - llvm::cl::desc("Generates SYCL code applying more aggressive assumptions that potentially\n" - "may alter the semantics of your program. Default: off."), - cat(DPCTCat), init(false)); - -static opt NoIncrementalMigration( - "no-incremental-migration", - llvm::cl::desc("Tells the tool to not perform an incremental migration.\n" - "Default: off (incremental migration happens)."), - cat(DPCTCat), init(false)); - -static opt QueryApiMapping("query-api-mapping", - llvm::cl::desc("Provides functionally compatible SYCL API mapping for CUDA API."), - value_desc("api"), cat(DPCTCat), llvm::cl::Optional); +static std::string SuppressWarningsMessage = "Comma separated list of migration warnings to suppress. Valid " + "warning IDs range\n" + "from " + std::to_string((size_t)Warnings::BEGIN) + " to " + + std::to_string((size_t)Warnings::END - 1) + + ". Hyphen separated ranges are also allowed. For example:\n" + "--suppress-warnings=1000-1010,1011."; + +#define DPCT_OPTIONS_IN_CLANG_DPCT +#define DPCT_OPT_TYPE(...) __VA_ARGS__ +#define DPCT_OPT_ENUM(NAME, ...) \ +llvm::cl::OptionEnumValue{NAME, __VA_ARGS__} +#define DPCT_OPTION_VALUES(...) \ +llvm::cl::values(__VA_ARGS__) +#define DPCT_NON_ENUM_OPTION(OPT_TYPE, OPT_VAR, OPTION_NAME, ...) \ +OPT_TYPE OPT_VAR(OPTION_NAME, __VA_ARGS__); +#define DPCT_ENUM_OPTION(OPT_TYPE, OPT_VAR, OPTION_NAME, ...) \ +OPT_TYPE OPT_VAR(OPTION_NAME, __VA_ARGS__); +#include "clang/DPCT/DPCTOptions.inc" +#undef DPCT_ENUM_OPTION +#undef DPCT_NON_ENUM_OPTION +#undef DPCT_OPTION_VALUES +#undef DPCT_OPT_ENUM +#undef DPCT_OPT_TYPE +#undef DPCT_OPTIONS_IN_CLANG_DPCT + +static llvm::cl::opt SDKPath("cuda-path", desc("Directory path of SDK.\n"), + llvm::cl::value_desc("dir"), llvm::cl::cat(DPCTCat), + llvm::cl::Optional, llvm::cl::Hidden); +static llvm::cl::opt Passes( + "passes", + llvm::cl::desc("Comma separated list of migration passes, which will be applied.\n" + "Only the specified passes are applied."), + llvm::cl::value_desc("IterationSpaceBuiltinRule,..."), llvm::cl::cat(DPCTCat), + llvm::cl::Hidden); +#ifdef DPCT_DEBUG_BUILD +static llvm::cl::opt + DiagsContent("report-diags-content", + llvm::cl::desc("Diagnostics verbosity level. \"pass\": Basic migration " + "pass information. " + "\"transformation\": Detailed migration pass " + "transformation information."), + llvm::cl::value_desc("[pass|transformation]"), llvm::cl::cat(DPCTCat), + llvm::cl::Optional, llvm::cl::Hidden); +#endif +static llvm::cl::opt NoUseGenericSpace( + "no-use-generic-space", llvm::cl::desc("sycl::access::address_space::generic_space is not used during atomic\n" + " function's migration. Default: off.\n"), + llvm::cl::cat(DPCTCat), llvm::cl::location(NoUseGenericSpaceFlag), llvm::cl::ReallyHidden); +#ifdef __linux__ +static AutoCompletePrinter AutoCompletePrinterInstance; +static llvm::cl::opt> AutoComplete( + "autocomplete", llvm::cl::desc("List all options or enums which have the specified prefix.\n"), + llvm::cl::cat(DPCTCat), llvm::cl::ReallyHidden, llvm::cl::location(AutoCompletePrinterInstance)); +#endif // clang-format on // TODO: implement one of this for each source language. diff --git a/clang/lib/DPCT/cmake/libDPCT.cmake b/clang/lib/DPCT/cmake/libDPCT.cmake index 2c3609db6bcf..f73bdac22bfd 100644 --- a/clang/lib/DPCT/cmake/libDPCT.cmake +++ b/clang/lib/DPCT/cmake/libDPCT.cmake @@ -31,6 +31,7 @@ macro(build_lib_dpct) NCCLAPIMigration.cpp TypeLocRewriters.cpp QueryApiMapping.cpp + AutoComplete.cpp LIBCUAPIMigration.cpp CUBAPIMigration.cpp diff --git a/clang/lib/Tooling/CommonOptionsParser.cpp b/clang/lib/Tooling/CommonOptionsParser.cpp index 7e199c0a3e13..72df8989c419 100644 --- a/clang/lib/Tooling/CommonOptionsParser.cpp +++ b/clang/lib/Tooling/CommonOptionsParser.cpp @@ -113,25 +113,24 @@ llvm::Error CommonOptionsParser::init( #ifdef SYCLomatic_CUSTOMIZATION bool IsCudaFile = false; int OriArgc = argc; - static cl::opt BuildPath( - "p", - cl::desc("The directory path for the compilation database (compile_commands.json). When no\n" - "path is specified, a search for compile_commands.json is attempted through all\n" - "parent directories of the first input source file."), - cl::Optional, cl::cat(Category), cl::value_desc("dir"), - cl::sub(*cl::AllSubCommands)); +#define DPCT_OPTIONS_IN_CLANG_TOOLING +#define DPCT_OPT_TYPE(...) __VA_ARGS__ +#define DPCT_NON_ENUM_OPTION(OPT_TYPE, OPT_VAR, OPTION_NAME, ...) \ +OPT_TYPE OPT_VAR(OPTION_NAME, __VA_ARGS__); +#include "clang/DPCT/DPCTOptions.inc" +#undef DPCT_NON_ENUM_OPTION +#undef DPCT_OPT_TYPE +#undef DPCT_OPTIONS_IN_CLANG_TOOLING + + static llvm::cl::list SourcePaths( + llvm::cl::Positional, llvm::cl::desc("[ ... ]"), llvm::cl::ZeroOrMore, + llvm::cl::cat(Category), llvm::cl::sub(*llvm::cl::AllSubCommands)); - static cl::list SourcePaths( - cl::Positional, cl::desc("[ ... ]"), llvm::cl::ZeroOrMore, - cl::cat(Category), cl::sub(*cl::AllSubCommands)); -#ifdef _WIN32 - static cl::opt - VcxprojFile("vcxprojfile", - cl::desc("The file path of vcxproj."), - cl::value_desc("file"), - cl::Optional, cl::cat(Category), - cl::sub(*cl::AllSubCommands)); -#endif + static cl::list ArgsBefore( + "extra-arg-before", + cl::desc("Additional argument to prepend to the compiler command line.\n" + "Refer to extra-arg option.\n"), + cl::cat(Category), cl::sub(*cl::AllSubCommands), llvm::cl::Hidden); #else static cl::opt BuildPath("p", cl::desc("Build path"), cl::Optional, cl::cat(Category), @@ -140,22 +139,7 @@ llvm::Error CommonOptionsParser::init( static cl::list SourcePaths( cl::Positional, cl::desc(" [... ]"), OccurrencesFlag, cl::cat(Category), cl::sub(*cl::AllSubCommands)); -#endif // SYCLomatic_CUSTOMIZATION - -#ifdef SYCLomatic_CUSTOMIZATION - static cl::list ArgsAfter( - "extra-arg", - cl::desc("Additional argument to append to the migration command line, example:\n" - "--extra-arg=\"-I /path/to/header\". The options that can be passed this way can\n" - "be found with the dpct -- -help command."), - cl::value_desc("string"), cl::cat(Category), cl::sub(*cl::AllSubCommands)); - static cl::list ArgsBefore( - "extra-arg-before", - cl::desc("Additional argument to prepend to the compiler command line.\n" - "Refer to extra-arg option.\n"), - cl::cat(Category), cl::sub(*cl::AllSubCommands), llvm::cl::Hidden); -#else static cl::list ArgsAfter( "extra-arg", cl::desc("Additional argument to append to the compiler command line"), diff --git a/clang/test/dpct/autocomplete.c b/clang/test/dpct/autocomplete.c new file mode 100644 index 000000000000..480ae96b1fbc --- /dev/null +++ b/clang/test/dpct/autocomplete.c @@ -0,0 +1,56 @@ +// UNSUPPORTED: -windows- + +// RUN: dpct --autocomplete= +// RUN: dpct --autocomplete=, +// RUN: dpct --autocomplete== +// RUN: dpct --autocomplete=,, +// RUN: dpct --autocomplete=- +// RUN: dpct --autocomplete=## +// RUN: dpct --autocomplete=# + +// RUN: dpct --autocomplete=--gen-build | FileCheck %s -check-prefix=DASHDASHGENBUILD +// DASHDASHGENBUILD: --gen-build-script +// RUN: dpct --autocomplete=-gen-build | FileCheck %s -check-prefix=DASHGENBUILD +// DASHGENBUILD: -gen-build-script +// RUN: dpct --autocomplete=foo | FileCheck %s -check-prefix=FOO +// FOO-NOT: foo +// RUN: dpct --autocomplete=--output-verbosity=#d | FileCheck %s -check-prefix=DASHDASHOUTPUTVEBD +// DASHDASHOUTPUTVEBD: detailed +// DASHDASHOUTPUTVEBD-NEXT: diagnostics +// RUN: dpct --autocomplete=-output-verbosity=#d | FileCheck %s -check-prefix=DASHOUTPUTVEBD +// DASHOUTPUTVEBD: detailed +// DASHOUTPUTVEBD-NEXT: diagnostics +// RUN: dpct --autocomplete=--output-verbosity= | FileCheck %s -check-prefix=DASHDASHOUTPUTVEBALL +// DASHDASHOUTPUTVEBALL: detailed +// DASHDASHOUTPUTVEBALL-NEXT: diagnostics +// DASHDASHOUTPUTVEBALL-NEXT: normal +// DASHDASHOUTPUTVEBALL-NEXT: silent +// RUN: dpct --autocomplete=-output-verbosity= | FileCheck %s -check-prefix=DASHOUTPUTVEBALL +// DASHOUTPUTVEBALL: detailed +// DASHOUTPUTVEBALL-NEXT: diagnostics +// DASHOUTPUTVEBALL-NEXT: normal +// DASHOUTPUTVEBALL-NEXT: silent + +// RUN: dpct --autocomplete=foo#bar##--enable | FileCheck %s -check-prefix=ENABLECTAD +// ENABLECTAD: --enable-ctad +// RUN: dpct --autocomplete=foo#bar###--format-range=#a | FileCheck %s -check-prefix=FORMATRANGE-ALL +// FORMATRANGE-ALL: all + +// RUN: dpct --autocomplete=--rule-file= | FileCheck %s -check-prefix=RULE_FILE_EQUAL +// RULE_FILE_EQUAL-NOT: --rule-file= +// RUN: dpct --autocomplete=--rule-file | FileCheck %s -check-prefix=RULE_FILE +// RULE_FILE: --rule-file +// RUN: dpct --autocomplete=-p= | FileCheck %s -check-prefix=DATA_BASE_EQUAL +// DATA_BASE_EQUAL-NOT: -p= +// RUN: dpct --autocomplete=-p | FileCheck %s -check-prefix=DATA_BASE +// DATA_BASE: -p + +// RUN: dpct --autocomplete=--usm-level=#none,restricted#--use-explicit-namespace=#cl,sycl, | FileCheck %s -check-prefix=UEN_ALL +// UEN_ALL: cl,sycl,cl +// UEN_ALL-NEXT: cl,sycl,dpct +// UEN_ALL-NEXT: cl,sycl,none +// UEN_ALL-NEXT: cl,sycl,sycl +// UEN_ALL-NEXT: cl,sycl,sycl-math +// RUN: dpct --autocomplete=--usm-level=#none,restricted#--use-explicit-namespace=#cl,sycl,s | FileCheck %s -check-prefix=UEN_S +// UEN_S: cl,sycl,sycl +// UEN_S-NEXT: cl,sycl,sycl-math diff --git a/clang/tools/dpct/bash-autocomplete.sh b/clang/tools/dpct/bash-autocomplete.sh new file mode 100644 index 000000000000..599f4666a97f --- /dev/null +++ b/clang/tools/dpct/bash-autocomplete.sh @@ -0,0 +1,66 @@ +# Please add "source /path/to/bash-autocomplete.sh" to your .bashrc to use this. + +_c2s_dpct_filedir() +{ + # _filedir function provided by recent versions of bash-completion package is + # better than "compgen -f" because the former honors spaces in pathnames while + # the latter doesn't. So we use compgen only when _filedir is not provided. + _filedir 2> /dev/null || COMPREPLY=( $( compgen -f ) ) +} + +_c2s_dpct() +{ + local cur prev words cword arg flags w1 w2 + # If latest bash-completion is not supported just initialize COMPREPLY and + # initialize variables by setting manually. + _init_completion -n 2> /dev/null + if [[ "$?" != 0 ]]; then + COMPREPLY=() + cword=$COMP_CWORD + cur="${COMP_WORDS[$cword]}" + fi + + w1="${COMP_WORDS[$cword - 1]}" + if [[ $cword > 1 ]]; then + w2="${COMP_WORDS[$cword - 2]}" + fi + + # Pass all the current command-line flags to c2s/dpct, so that c2s/dpct can handle + # these internally. + # '=' is separated differently by bash, so we have to concat them without '#' + for i in `seq 1 $cword`; do + if [[ $i == $cword || "${COMP_WORDS[$(($i+1))]}" == '=' ]]; then + arg="$arg${COMP_WORDS[$i]}" + else + arg="$arg${COMP_WORDS[$i]}#" + fi + done + + # expand ~ to $HOME + eval local path=${COMP_WORDS[0]} + # Use $'\t' so that bash expands the \t for older versions of sed. + flags=$( "$path" --autocomplete="$arg" 2>/dev/null | sed -e $'s/\t.*//' ) + # If c2s/dpct is old that it does not support --autocomplete, + # fall back to the filename completion. + if [[ "$?" != 0 ]]; then + _c2s_dpct_filedir + return + fi + + # When c2s/dpct does not emit any possible autocompletion, or user pushed tab after " ", + # just autocomplete files. + if [[ "$flags" == "$(echo -e '\n')" ]]; then + # If -foo= and there was no possible values, autocomplete files. + [[ "$cur" == '=' || "$cur" == -*= ]] && cur="" + _c2s_dpct_filedir + elif [[ "$cur" == '=' ]]; then + COMPREPLY=( $( compgen -W "$flags" -- "") ) + else + # Bash automatically appends a space after '=' by default. + # Disable it so that it works nicely for options in the form of -foo=bar. + [[ "${flags: -1}" == '=' ]] && compopt -o nospace 2> /dev/null + COMPREPLY=( $( compgen -W "$flags" -- "$cur" ) ) + fi +} +complete -F _c2s_dpct c2s +complete -F _c2s_dpct dpct diff --git a/clang/tools/dpct/cmake/dpct.cmake b/clang/tools/dpct/cmake/dpct.cmake index fd67bb0538eb..bf0544bf73e7 100644 --- a/clang/tools/dpct/cmake/dpct.cmake +++ b/clang/tools/dpct/cmake/dpct.cmake @@ -12,6 +12,7 @@ macro(set_dpct_package) install-dpct-headers install-clang-resource-headers install-dpct-binary + install-dpct-autocomplete install-dpct-opt-rules ) endif() @@ -24,4 +25,19 @@ macro(install_dpct) ) add_clang_symlink(c2s dpct-binary) + if(UNIX) + set(dpct_autocomplete_script bash-autocomplete.sh) + endif() + + if(UNIX) + install( + FILES ${dpct_autocomplete_script} + COMPONENT dpct-autocomplete + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + DESTINATION ./env) + if (NOT CMAKE_CONFIGURATION_TYPES) + add_llvm_install_targets(install-dpct-autocomplete + COMPONENT dpct-autocomplete) + endif() + endif() endmacro()