OpenCLOptions.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. //===--- OpenCLOptions.cpp---------------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "clang/Basic/OpenCLOptions.h"
  9. #include "clang/Basic/Diagnostic.h"
  10. #include "clang/Basic/TargetInfo.h"
  11. namespace clang {
  12. const OpenCLOptions::FeatureDepList OpenCLOptions::DependentFeaturesList = {
  13. {"__opencl_c_read_write_images", "__opencl_c_images"},
  14. {"__opencl_c_3d_image_writes", "__opencl_c_images"},
  15. {"__opencl_c_pipes", "__opencl_c_generic_address_space"},
  16. {"__opencl_c_device_enqueue", "__opencl_c_generic_address_space"},
  17. {"__opencl_c_device_enqueue", "__opencl_c_program_scope_global_variables"}};
  18. const llvm::StringMap<llvm::StringRef> OpenCLOptions::FeatureExtensionMap = {
  19. {"cl_khr_fp64", "__opencl_c_fp64"},
  20. {"cl_khr_3d_image_writes", "__opencl_c_3d_image_writes"}};
  21. bool OpenCLOptions::isKnown(llvm::StringRef Ext) const {
  22. return OptMap.find(Ext) != OptMap.end();
  23. }
  24. bool OpenCLOptions::isAvailableOption(llvm::StringRef Ext,
  25. const LangOptions &LO) const {
  26. if (!isKnown(Ext))
  27. return false;
  28. auto &OptInfo = OptMap.find(Ext)->getValue();
  29. if (OptInfo.isCoreIn(LO) || OptInfo.isOptionalCoreIn(LO))
  30. return isSupported(Ext, LO);
  31. return isEnabled(Ext);
  32. }
  33. bool OpenCLOptions::isEnabled(llvm::StringRef Ext) const {
  34. auto I = OptMap.find(Ext);
  35. return I != OptMap.end() && I->getValue().Enabled;
  36. }
  37. bool OpenCLOptions::isWithPragma(llvm::StringRef Ext) const {
  38. auto E = OptMap.find(Ext);
  39. return E != OptMap.end() && E->second.WithPragma;
  40. }
  41. bool OpenCLOptions::isSupported(llvm::StringRef Ext,
  42. const LangOptions &LO) const {
  43. auto I = OptMap.find(Ext);
  44. return I != OptMap.end() && I->getValue().Supported &&
  45. I->getValue().isAvailableIn(LO);
  46. }
  47. bool OpenCLOptions::isSupportedCore(llvm::StringRef Ext,
  48. const LangOptions &LO) const {
  49. auto I = OptMap.find(Ext);
  50. return I != OptMap.end() && I->getValue().Supported &&
  51. I->getValue().isCoreIn(LO);
  52. }
  53. bool OpenCLOptions::isSupportedOptionalCore(llvm::StringRef Ext,
  54. const LangOptions &LO) const {
  55. auto I = OptMap.find(Ext);
  56. return I != OptMap.end() && I->getValue().Supported &&
  57. I->getValue().isOptionalCoreIn(LO);
  58. }
  59. bool OpenCLOptions::isSupportedCoreOrOptionalCore(llvm::StringRef Ext,
  60. const LangOptions &LO) const {
  61. return isSupportedCore(Ext, LO) || isSupportedOptionalCore(Ext, LO);
  62. }
  63. bool OpenCLOptions::isSupportedExtension(llvm::StringRef Ext,
  64. const LangOptions &LO) const {
  65. auto I = OptMap.find(Ext);
  66. return I != OptMap.end() && I->getValue().Supported &&
  67. I->getValue().isAvailableIn(LO) &&
  68. !isSupportedCoreOrOptionalCore(Ext, LO);
  69. }
  70. void OpenCLOptions::enable(llvm::StringRef Ext, bool V) {
  71. OptMap[Ext].Enabled = V;
  72. }
  73. void OpenCLOptions::acceptsPragma(llvm::StringRef Ext, bool V) {
  74. OptMap[Ext].WithPragma = V;
  75. }
  76. void OpenCLOptions::support(llvm::StringRef Ext, bool V) {
  77. assert(!Ext.empty() && "Extension is empty.");
  78. assert(Ext[0] != '+' && Ext[0] != '-');
  79. OptMap[Ext].Supported = V;
  80. }
  81. OpenCLOptions::OpenCLOptions() {
  82. #define OPENCL_GENERIC_EXTENSION(Ext, ...) \
  83. OptMap.insert_or_assign(#Ext, OpenCLOptionInfo{__VA_ARGS__});
  84. #include "clang/Basic/OpenCLExtensions.def"
  85. }
  86. void OpenCLOptions::addSupport(const llvm::StringMap<bool> &FeaturesMap,
  87. const LangOptions &Opts) {
  88. for (const auto &F : FeaturesMap) {
  89. const auto &Name = F.getKey();
  90. if (F.getValue() && isKnown(Name) && OptMap[Name].isAvailableIn(Opts))
  91. support(Name);
  92. }
  93. }
  94. void OpenCLOptions::disableAll() {
  95. for (auto &Opt : OptMap)
  96. Opt.getValue().Enabled = false;
  97. }
  98. bool OpenCLOptions::diagnoseUnsupportedFeatureDependencies(
  99. const TargetInfo &TI, DiagnosticsEngine &Diags) {
  100. auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts();
  101. bool IsValid = true;
  102. for (auto &FeaturePair : DependentFeaturesList) {
  103. auto Feature = FeaturePair.first;
  104. auto Dep = FeaturePair.second;
  105. if (TI.hasFeatureEnabled(OpenCLFeaturesMap, Feature) &&
  106. !TI.hasFeatureEnabled(OpenCLFeaturesMap, Dep)) {
  107. IsValid = false;
  108. Diags.Report(diag::err_opencl_feature_requires) << Feature << Dep;
  109. }
  110. }
  111. return IsValid;
  112. }
  113. bool OpenCLOptions::diagnoseFeatureExtensionDifferences(
  114. const TargetInfo &TI, DiagnosticsEngine &Diags) {
  115. auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts();
  116. bool IsValid = true;
  117. for (auto &ExtAndFeat : FeatureExtensionMap)
  118. if (TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.getKey()) !=
  119. TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.getValue())) {
  120. IsValid = false;
  121. Diags.Report(diag::err_opencl_extension_and_feature_differs)
  122. << ExtAndFeat.getKey() << ExtAndFeat.getValue();
  123. }
  124. return IsValid;
  125. }
  126. } // end namespace clang