Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/include/clang/Basic/SyncScope.h
Line
Count
Source (jump to first uncovered line)
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
  OpenCLWorkGroup,
44
  OpenCLDevice,
45
  OpenCLAllSVMDevices,
46
  OpenCLSubGroup,
47
  Last = OpenCLSubGroup
48
};
49
50
32
inline llvm::StringRef getAsString(SyncScope S) {
51
32
  switch (S) {
52
32
  case SyncScope::OpenCLWorkGroup:
53
8
    return "opencl_workgroup";
54
32
  case SyncScope::OpenCLDevice:
55
8
    return "opencl_device";
56
32
  case SyncScope::OpenCLAllSVMDevices:
57
8
    return "opencl_allsvmdevices";
58
32
  case SyncScope::OpenCLSubGroup:
59
8
    return "opencl_subgroup";
60
0
  }
61
0
  llvm_unreachable("Invalid synch scope");
62
0
}
63
64
/// Defines the kind of atomic scope models.
65
enum class AtomicScopeModelKind { None, OpenCL };
66
67
/// Defines the interface for synch scope model.
68
class AtomicScopeModel {
69
public:
70
388
  virtual ~AtomicScopeModel() {}
71
  /// Maps language specific synch scope values to internal
72
  /// SyncScope enum.
73
  virtual SyncScope map(unsigned S) const = 0;
74
75
  /// Check if the compile-time constant synch scope value
76
  /// is valid.
77
  virtual bool isValid(unsigned S) const = 0;
78
79
  /// Get all possible synch scope values that might be
80
  /// encountered at runtime for the current language.
81
  virtual ArrayRef<unsigned> getRuntimeValues() const = 0;
82
83
  /// If atomic builtin function is called with invalid
84
  /// synch scope value at runtime, it will fall back to a valid
85
  /// synch scope value returned by this function.
86
  virtual unsigned getFallBackValue() const = 0;
87
88
  /// Create an atomic scope model by AtomicScopeModelKind.
89
  /// \return an empty std::unique_ptr for AtomicScopeModelKind::None.
90
  static std::unique_ptr<AtomicScopeModel> create(AtomicScopeModelKind K);
91
};
92
93
/// Defines the synch scope model for OpenCL.
94
class AtomicScopeOpenCLModel : public AtomicScopeModel {
95
public:
96
  /// The enum values match the pre-defined macros
97
  /// __OPENCL_MEMORY_SCOPE_*, which are used to define memory_scope_*
98
  /// enums in opencl-c-base.h.
99
  enum ID {
100
    WorkGroup = 1,
101
    Device = 2,
102
    AllSVMDevices = 3,
103
    SubGroup = 4,
104
    Last = SubGroup
105
  };
106
107
388
  AtomicScopeOpenCLModel() {}
108
109
114
  SyncScope map(unsigned S) const override {
110
114
    switch (static_cast<ID>(S)) {
111
114
    case WorkGroup:
112
60
      return SyncScope::OpenCLWorkGroup;
113
114
    case Device:
114
18
      return SyncScope::OpenCLDevice;
115
114
    case AllSVMDevices:
116
18
      return SyncScope::OpenCLAllSVMDevices;
117
114
    case SubGroup:
118
18
      return SyncScope::OpenCLSubGroup;
119
0
    }
120
0
    llvm_unreachable("Invalid language synch scope value");
121
0
  }
122
123
245
  bool isValid(unsigned S) const override {
124
245
    return S >= static_cast<unsigned>(WorkGroup) &&
125
245
           
S <= static_cast<unsigned>(Last)243
;
126
245
  }
127
128
8
  ArrayRef<unsigned> getRuntimeValues() const override {
129
8
    static_assert(Last == SubGroup, "Does not include all synch scopes");
130
8
    static const unsigned Scopes[] = {
131
8
        static_cast<unsigned>(WorkGroup), static_cast<unsigned>(Device),
132
8
        static_cast<unsigned>(AllSVMDevices), static_cast<unsigned>(SubGroup)};
133
8
    return llvm::makeArrayRef(Scopes);
134
8
  }
135
136
8
  unsigned getFallBackValue() const override {
137
8
    return static_cast<unsigned>(AllSVMDevices);
138
8
  }
139
};
140
141
inline std::unique_ptr<AtomicScopeModel>
142
4.84k
AtomicScopeModel::create(AtomicScopeModelKind K) {
143
4.84k
  switch (K) {
144
4.84k
  case AtomicScopeModelKind::None:
145
4.45k
    return std::unique_ptr<AtomicScopeModel>{};
146
4.84k
  case AtomicScopeModelKind::OpenCL:
147
388
    return llvm::make_unique<AtomicScopeOpenCLModel>();
148
0
  }
149
0
  llvm_unreachable("Invalid atomic scope model kind");
150
0
}
151
}
152
153
#endif