Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===--- SyncScope.h - Atomic synchronization scopes ------------*- 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. ///
  9. /// \file
  10. /// Provides definitions for the atomic synchronization scopes.
  11. ///
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_CLANG_BASIC_SYNCSCOPE_H
  15. #define LLVM_CLANG_BASIC_SYNCSCOPE_H
  16.  
  17. #include "clang/Basic/LangOptions.h"
  18. #include "llvm/ADT/ArrayRef.h"
  19. #include "llvm/ADT/StringRef.h"
  20. #include <memory>
  21.  
  22. namespace clang {
  23.  
  24. /// Defines synch scope values used internally by clang.
  25. ///
  26. /// The enum values start from 0 and are contiguous. They are mainly used for
  27. /// enumerating all supported synch scope values and mapping them to LLVM
  28. /// synch scopes. Their numerical values may be different from the corresponding
  29. /// synch scope enums used in source languages.
  30. ///
  31. /// In atomic builtin and expressions, language-specific synch scope enums are
  32. /// used. Currently only OpenCL memory scope enums are supported and assumed
  33. /// to be used by all languages. However, in the future, other languages may
  34. /// define their own set of synch scope enums. The language-specific synch scope
  35. /// values are represented by class AtomicScopeModel and its derived classes.
  36. ///
  37. /// To add a new enum value:
  38. ///   Add the enum value to enum class SyncScope.
  39. ///   Update enum value Last if necessary.
  40. ///   Update getAsString.
  41. ///
  42. enum class SyncScope {
  43.   HIPSingleThread,
  44.   HIPWavefront,
  45.   HIPWorkgroup,
  46.   HIPAgent,
  47.   HIPSystem,
  48.   OpenCLWorkGroup,
  49.   OpenCLDevice,
  50.   OpenCLAllSVMDevices,
  51.   OpenCLSubGroup,
  52.   Last = OpenCLSubGroup
  53. };
  54.  
  55. inline llvm::StringRef getAsString(SyncScope S) {
  56.   switch (S) {
  57.   case SyncScope::HIPSingleThread:
  58.     return "hip_singlethread";
  59.   case SyncScope::HIPWavefront:
  60.     return "hip_wavefront";
  61.   case SyncScope::HIPWorkgroup:
  62.     return "hip_workgroup";
  63.   case SyncScope::HIPAgent:
  64.     return "hip_agent";
  65.   case SyncScope::HIPSystem:
  66.     return "hip_system";
  67.   case SyncScope::OpenCLWorkGroup:
  68.     return "opencl_workgroup";
  69.   case SyncScope::OpenCLDevice:
  70.     return "opencl_device";
  71.   case SyncScope::OpenCLAllSVMDevices:
  72.     return "opencl_allsvmdevices";
  73.   case SyncScope::OpenCLSubGroup:
  74.     return "opencl_subgroup";
  75.   }
  76.   llvm_unreachable("Invalid synch scope");
  77. }
  78.  
  79. /// Defines the kind of atomic scope models.
  80. enum class AtomicScopeModelKind { None, OpenCL, HIP };
  81.  
  82. /// Defines the interface for synch scope model.
  83. class AtomicScopeModel {
  84. public:
  85.   virtual ~AtomicScopeModel() {}
  86.   /// Maps language specific synch scope values to internal
  87.   /// SyncScope enum.
  88.   virtual SyncScope map(unsigned S) const = 0;
  89.  
  90.   /// Check if the compile-time constant synch scope value
  91.   /// is valid.
  92.   virtual bool isValid(unsigned S) const = 0;
  93.  
  94.   /// Get all possible synch scope values that might be
  95.   /// encountered at runtime for the current language.
  96.   virtual ArrayRef<unsigned> getRuntimeValues() const = 0;
  97.  
  98.   /// If atomic builtin function is called with invalid
  99.   /// synch scope value at runtime, it will fall back to a valid
  100.   /// synch scope value returned by this function.
  101.   virtual unsigned getFallBackValue() const = 0;
  102.  
  103.   /// Create an atomic scope model by AtomicScopeModelKind.
  104.   /// \return an empty std::unique_ptr for AtomicScopeModelKind::None.
  105.   static std::unique_ptr<AtomicScopeModel> create(AtomicScopeModelKind K);
  106. };
  107.  
  108. /// Defines the synch scope model for OpenCL.
  109. class AtomicScopeOpenCLModel : public AtomicScopeModel {
  110. public:
  111.   /// The enum values match the pre-defined macros
  112.   /// __OPENCL_MEMORY_SCOPE_*, which are used to define memory_scope_*
  113.   /// enums in opencl-c-base.h.
  114.   enum ID {
  115.     WorkGroup = 1,
  116.     Device = 2,
  117.     AllSVMDevices = 3,
  118.     SubGroup = 4,
  119.     Last = SubGroup
  120.   };
  121.  
  122.   AtomicScopeOpenCLModel() {}
  123.  
  124.   SyncScope map(unsigned S) const override {
  125.     switch (static_cast<ID>(S)) {
  126.     case WorkGroup:
  127.       return SyncScope::OpenCLWorkGroup;
  128.     case Device:
  129.       return SyncScope::OpenCLDevice;
  130.     case AllSVMDevices:
  131.       return SyncScope::OpenCLAllSVMDevices;
  132.     case SubGroup:
  133.       return SyncScope::OpenCLSubGroup;
  134.     }
  135.     llvm_unreachable("Invalid language synch scope value");
  136.   }
  137.  
  138.   bool isValid(unsigned S) const override {
  139.     return S >= static_cast<unsigned>(WorkGroup) &&
  140.            S <= static_cast<unsigned>(Last);
  141.   }
  142.  
  143.   ArrayRef<unsigned> getRuntimeValues() const override {
  144.     static_assert(Last == SubGroup, "Does not include all synch scopes");
  145.     static const unsigned Scopes[] = {
  146.         static_cast<unsigned>(WorkGroup), static_cast<unsigned>(Device),
  147.         static_cast<unsigned>(AllSVMDevices), static_cast<unsigned>(SubGroup)};
  148.     return llvm::ArrayRef(Scopes);
  149.   }
  150.  
  151.   unsigned getFallBackValue() const override {
  152.     return static_cast<unsigned>(AllSVMDevices);
  153.   }
  154. };
  155.  
  156. /// Defines the synch scope model for HIP.
  157. class AtomicScopeHIPModel : public AtomicScopeModel {
  158. public:
  159.   /// The enum values match the pre-defined macros
  160.   /// __HIP_MEMORY_SCOPE_*, which are used to define memory_scope_*
  161.   /// enums in hip-c.h.
  162.   enum ID {
  163.     SingleThread = 1,
  164.     Wavefront = 2,
  165.     Workgroup = 3,
  166.     Agent = 4,
  167.     System = 5,
  168.     Last = System
  169.   };
  170.  
  171.   AtomicScopeHIPModel() {}
  172.  
  173.   SyncScope map(unsigned S) const override {
  174.     switch (static_cast<ID>(S)) {
  175.     case SingleThread:
  176.       return SyncScope::HIPSingleThread;
  177.     case Wavefront:
  178.       return SyncScope::HIPWavefront;
  179.     case Workgroup:
  180.       return SyncScope::HIPWorkgroup;
  181.     case Agent:
  182.       return SyncScope::HIPAgent;
  183.     case System:
  184.       return SyncScope::HIPSystem;
  185.     }
  186.     llvm_unreachable("Invalid language synch scope value");
  187.   }
  188.  
  189.   bool isValid(unsigned S) const override {
  190.     return S >= static_cast<unsigned>(SingleThread) &&
  191.            S <= static_cast<unsigned>(Last);
  192.   }
  193.  
  194.   ArrayRef<unsigned> getRuntimeValues() const override {
  195.     static_assert(Last == System, "Does not include all synch scopes");
  196.     static const unsigned Scopes[] = {
  197.         static_cast<unsigned>(SingleThread), static_cast<unsigned>(Wavefront),
  198.         static_cast<unsigned>(Workgroup), static_cast<unsigned>(Agent),
  199.         static_cast<unsigned>(System)};
  200.     return llvm::ArrayRef(Scopes);
  201.   }
  202.  
  203.   unsigned getFallBackValue() const override {
  204.     return static_cast<unsigned>(System);
  205.   }
  206. };
  207.  
  208. inline std::unique_ptr<AtomicScopeModel>
  209. AtomicScopeModel::create(AtomicScopeModelKind K) {
  210.   switch (K) {
  211.   case AtomicScopeModelKind::None:
  212.     return std::unique_ptr<AtomicScopeModel>{};
  213.   case AtomicScopeModelKind::OpenCL:
  214.     return std::make_unique<AtomicScopeOpenCLModel>();
  215.   case AtomicScopeModelKind::HIP:
  216.     return std::make_unique<AtomicScopeHIPModel>();
  217.   }
  218.   llvm_unreachable("Invalid atomic scope model kind");
  219. }
  220. } // namespace clang
  221.  
  222. #endif
  223.