Coverage Report

Created: 2018-09-25 23:22

/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
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
///
10
/// \file
11
/// Provides definitions for the atomic synchronization scopes.
12
///
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_CLANG_BASIC_SYNCSCOPE_H
16
#define LLVM_CLANG_BASIC_SYNCSCOPE_H
17
18
#include "clang/Basic/LangOptions.h"
19
#include "llvm/ADT/ArrayRef.h"
20
#include "llvm/ADT/StringRef.h"
21
#include <memory>
22
23
namespace clang {
24
25
/// Defines synch scope values used internally by clang.
26
///
27
/// The enum values start from 0 and are contiguous. They are mainly used for
28
/// enumerating all supported synch scope values and mapping them to LLVM
29
/// synch scopes. Their numerical values may be different from the corresponding
30
/// synch scope enums used in source languages.
31
///
32
/// In atomic builtin and expressions, language-specific synch scope enums are
33
/// used. Currently only OpenCL memory scope enums are supported and assumed
34
/// to be used by all languages. However, in the future, other languages may
35
/// define their own set of synch scope enums. The language-specific synch scope
36
/// values are represented by class AtomicScopeModel and its derived classes.
37
///
38
/// To add a new enum value:
39
///   Add the enum value to enum class SyncScope.
40
///   Update enum value Last if necessary.
41
///   Update getAsString.
42
///
43
enum class SyncScope {
44
  OpenCLWorkGroup,
45
  OpenCLDevice,
46
  OpenCLAllSVMDevices,
47
  OpenCLSubGroup,
48
  Last = OpenCLSubGroup
49
};
50
51
32
inline llvm::StringRef getAsString(SyncScope S) {
52
32
  switch (S) {
53
32
  case SyncScope::OpenCLWorkGroup:
54
8
    return "opencl_workgroup";
55
32
  case SyncScope::OpenCLDevice:
56
8
    return "opencl_device";
57
32
  case SyncScope::OpenCLAllSVMDevices:
58
8
    return "opencl_allsvmdevices";
59
32
  case SyncScope::OpenCLSubGroup:
60
8
    return "opencl_subgroup";
61
0
  }
62
0
  llvm_unreachable("Invalid synch scope");
63
0
}
64
65
/// Defines the kind of atomic scope models.
66
enum class AtomicScopeModelKind { None, OpenCL };
67
68
/// Defines the interface for synch scope model.
69
class AtomicScopeModel {
70
public:
71
388
  virtual ~AtomicScopeModel() {}
72
  /// Maps language specific synch scope values to internal
73
  /// SyncScope enum.
74
  virtual SyncScope map(unsigned S) const = 0;
75
76
  /// Check if the compile-time constant synch scope value
77
  /// is valid.
78
  virtual bool isValid(unsigned S) const = 0;
79
80
  /// Get all possible synch scope values that might be
81
  /// encountered at runtime for the current language.
82
  virtual ArrayRef<unsigned> getRuntimeValues() const = 0;
83
84
  /// If atomic builtin function is called with invalid
85
  /// synch scope value at runtime, it will fall back to a valid
86
  /// synch scope value returned by this function.
87
  virtual unsigned getFallBackValue() const = 0;
88
89
  /// Create an atomic scope model by AtomicScopeModelKind.
90
  /// \return an empty std::unique_ptr for AtomicScopeModelKind::None.
91
  static std::unique_ptr<AtomicScopeModel> create(AtomicScopeModelKind K);
92
};
93
94
/// Defines the synch scope model for OpenCL.
95
class AtomicScopeOpenCLModel : public AtomicScopeModel {
96
public:
97
  /// The enum values match the pre-defined macros
98
  /// __OPENCL_MEMORY_SCOPE_*, which are used to define memory_scope_*
99
  /// enums in opencl-c.h.
100
  enum ID {
101
    WorkGroup = 1,
102
    Device = 2,
103
    AllSVMDevices = 3,
104
    SubGroup = 4,
105
    Last = SubGroup
106
  };
107
108
388
  AtomicScopeOpenCLModel() {}
109
110
114
  SyncScope map(unsigned S) const override {
111
114
    switch (static_cast<ID>(S)) {
112
114
    case WorkGroup:
113
60
      return SyncScope::OpenCLWorkGroup;
114
114
    case Device:
115
18
      return SyncScope::OpenCLDevice;
116
114
    case AllSVMDevices:
117
18
      return SyncScope::OpenCLAllSVMDevices;
118
114
    case SubGroup:
119
18
      return SyncScope::OpenCLSubGroup;
120
0
    }
121
0
    llvm_unreachable("Invalid language synch scope value");
122
0
  }
123
124
245
  bool isValid(unsigned S) const override {
125
245
    return S >= static_cast<unsigned>(WorkGroup) &&
126
245
           
S <= static_cast<unsigned>(Last)243
;
127
245
  }
128
129
8
  ArrayRef<unsigned> getRuntimeValues() const override {
130
8
    static_assert(Last == SubGroup, "Does not include all synch scopes");
131
8
    static const unsigned Scopes[] = {
132
8
        static_cast<unsigned>(WorkGroup), static_cast<unsigned>(Device),
133
8
        static_cast<unsigned>(AllSVMDevices), static_cast<unsigned>(SubGroup)};
134
8
    return llvm::makeArrayRef(Scopes);
135
8
  }
136
137
8
  unsigned getFallBackValue() const override {
138
8
    return static_cast<unsigned>(AllSVMDevices);
139
8
  }
140
};
141
142
inline std::unique_ptr<AtomicScopeModel>
143
5.40k
AtomicScopeModel::create(AtomicScopeModelKind K) {
144
5.40k
  switch (K) {
145
5.40k
  case AtomicScopeModelKind::None:
146
5.02k
    return std::unique_ptr<AtomicScopeModel>{};
147
5.40k
  case AtomicScopeModelKind::OpenCL:
148
388
    return llvm::make_unique<AtomicScopeOpenCLModel>();
149
0
  }
150
0
  llvm_unreachable("Invalid atomic scope model kind");
151
0
}
152
}
153
154
#endif