Coverage Report

Created: 2021-09-21 08:58

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/Targets/WebAssembly.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- WebAssembly.cpp - Implement WebAssembly target feature support ---===//
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
// This file implements WebAssembly TargetInfo objects.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "WebAssembly.h"
14
#include "Targets.h"
15
#include "clang/Basic/Builtins.h"
16
#include "clang/Basic/Diagnostic.h"
17
#include "clang/Basic/TargetBuiltins.h"
18
#include "llvm/ADT/StringSwitch.h"
19
20
using namespace clang;
21
using namespace clang::targets;
22
23
const Builtin::Info WebAssemblyTargetInfo::BuiltinInfo[] = {
24
#define BUILTIN(ID, TYPE, ATTRS)                                               \
25
  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
26
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
27
  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
28
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
29
  {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
30
#include "clang/Basic/BuiltinsWebAssembly.def"
31
};
32
33
static constexpr llvm::StringLiteral ValidCPUNames[] = {
34
    {"mvp"}, {"bleeding-edge"}, {"generic"}};
35
36
138
StringRef WebAssemblyTargetInfo::getABI() const { return ABI; }
37
38
1
bool WebAssemblyTargetInfo::setABI(const std::string &Name) {
39
1
  if (Name != "mvp" && Name != "experimental-mv")
40
0
    return false;
41
42
1
  ABI = Name;
43
1
  return true;
44
1
}
45
46
98
bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const {
47
98
  return llvm::StringSwitch<bool>(Feature)
48
98
      .Case("simd128", SIMDLevel >= SIMD128)
49
98
      .Case("nontrapping-fptoint", HasNontrappingFPToInt)
50
98
      .Case("sign-ext", HasSignExt)
51
98
      .Case("exception-handling", HasExceptionHandling)
52
98
      .Case("bulk-memory", HasBulkMemory)
53
98
      .Case("atomics", HasAtomics)
54
98
      .Case("mutable-globals", HasMutableGlobals)
55
98
      .Case("multivalue", HasMultivalue)
56
98
      .Case("tail-call", HasTailCall)
57
98
      .Case("reference-types", HasReferenceTypes)
58
98
      .Default(false);
59
98
}
60
61
35
bool WebAssemblyTargetInfo::isValidCPUName(StringRef Name) const {
62
35
  return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames);
63
35
}
64
65
void WebAssemblyTargetInfo::fillValidCPUList(
66
1
    SmallVectorImpl<StringRef> &Values) const {
67
1
  Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
68
1
}
69
70
void WebAssemblyTargetInfo::getTargetDefines(const LangOptions &Opts,
71
94
                                             MacroBuilder &Builder) const {
72
94
  defineCPUMacros(Builder, "wasm", /*Tuning=*/false);
73
94
  if (SIMDLevel >= SIMD128)
74
8
    Builder.defineMacro("__wasm_simd128__");
75
94
  if (HasNontrappingFPToInt)
76
9
    Builder.defineMacro("__wasm_nontrapping_fptoint__");
77
94
  if (HasSignExt)
78
10
    Builder.defineMacro("__wasm_sign_ext__");
79
94
  if (HasExceptionHandling)
80
11
    Builder.defineMacro("__wasm_exception_handling__");
81
94
  if (HasBulkMemory)
82
13
    Builder.defineMacro("__wasm_bulk_memory__");
83
94
  if (HasAtomics)
84
15
    Builder.defineMacro("__wasm_atomics__");
85
94
  if (HasMutableGlobals)
86
10
    Builder.defineMacro("__wasm_mutable_globals__");
87
94
  if (HasMultivalue)
88
2
    Builder.defineMacro("__wasm_multivalue__");
89
94
  if (HasTailCall)
90
6
    Builder.defineMacro("__wasm_tail_call__");
91
94
  if (HasReferenceTypes)
92
2
    Builder.defineMacro("__wasm_reference_types__");
93
94
}
94
95
void WebAssemblyTargetInfo::setSIMDLevel(llvm::StringMap<bool> &Features,
96
1.89k
                                         SIMDEnum Level, bool Enabled) {
97
1.89k
  if (Enabled) {
98
1.89k
    switch (Level) {
99
1.89k
    case SIMD128:
100
1.89k
      Features["simd128"] = true;
101
1.89k
      LLVM_FALLTHROUGH;
102
1.89k
    case NoSIMD:
103
1.89k
      break;
104
1.89k
    }
105
1.89k
    return;
106
1.89k
  }
107
108
2
  switch (Level) {
109
0
  case NoSIMD:
110
2
  case SIMD128:
111
2
    Features["simd128"] = false;
112
2
    break;
113
2
  }
114
2
}
115
116
void WebAssemblyTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
117
                                              StringRef Name,
118
1.94k
                                              bool Enabled) const {
119
1.94k
  if (Name == "simd128")
120
1.89k
    setSIMDLevel(Features, SIMD128, Enabled);
121
54
  else
122
54
    Features[Name] = Enabled;
123
1.94k
}
124
125
bool WebAssemblyTargetInfo::initFeatureMap(
126
    llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
127
1.03k
    const std::vector<std::string> &FeaturesVec) const {
128
1.03k
  if (CPU == "bleeding-edge") {
129
4
    Features["nontrapping-fptoint"] = true;
130
4
    Features["sign-ext"] = true;
131
4
    Features["bulk-memory"] = true;
132
4
    Features["atomics"] = true;
133
4
    Features["mutable-globals"] = true;
134
4
    Features["tail-call"] = true;
135
4
    setSIMDLevel(Features, SIMD128, true);
136
4
  }
137
138
1.03k
  return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
139
1.03k
}
140
141
bool WebAssemblyTargetInfo::handleTargetFeatures(
142
95
    std::vector<std::string> &Features, DiagnosticsEngine &Diags) {
143
95
  for (const auto &Feature : Features) {
144
88
    if (Feature == "+simd128") {
145
8
      SIMDLevel = std::max(SIMDLevel, SIMD128);
146
8
      continue;
147
8
    }
148
80
    if (Feature == "-simd128") {
149
2
      SIMDLevel = std::min(SIMDLevel, SIMDEnum(SIMD128 - 1));
150
2
      continue;
151
2
    }
152
78
    if (Feature == "+nontrapping-fptoint") {
153
9
      HasNontrappingFPToInt = true;
154
9
      continue;
155
9
    }
156
69
    if (Feature == "-nontrapping-fptoint") {
157
0
      HasNontrappingFPToInt = false;
158
0
      continue;
159
0
    }
160
69
    if (Feature == "+sign-ext") {
161
10
      HasSignExt = true;
162
10
      continue;
163
10
    }
164
59
    if (Feature == "-sign-ext") {
165
0
      HasSignExt = false;
166
0
      continue;
167
0
    }
168
59
    if (Feature == "+exception-handling") {
169
11
      HasExceptionHandling = true;
170
11
      continue;
171
11
    }
172
48
    if (Feature == "-exception-handling") {
173
0
      HasExceptionHandling = false;
174
0
      continue;
175
0
    }
176
48
    if (Feature == "+bulk-memory") {
177
13
      HasBulkMemory = true;
178
13
      continue;
179
13
    }
180
35
    if (Feature == "-bulk-memory") {
181
0
      HasBulkMemory = false;
182
0
      continue;
183
0
    }
184
35
    if (Feature == "+atomics") {
185
15
      HasAtomics = true;
186
15
      continue;
187
15
    }
188
20
    if (Feature == "-atomics") {
189
0
      HasAtomics = false;
190
0
      continue;
191
0
    }
192
20
    if (Feature == "+mutable-globals") {
193
10
      HasMutableGlobals = true;
194
10
      continue;
195
10
    }
196
10
    if (Feature == "-mutable-globals") {
197
0
      HasMutableGlobals = false;
198
0
      continue;
199
0
    }
200
10
    if (Feature == "+multivalue") {
201
2
      HasMultivalue = true;
202
2
      continue;
203
2
    }
204
8
    if (Feature == "-multivalue") {
205
0
      HasMultivalue = false;
206
0
      continue;
207
0
    }
208
8
    if (Feature == "+tail-call") {
209
6
      HasTailCall = true;
210
6
      continue;
211
6
    }
212
2
    if (Feature == "-tail-call") {
213
0
      HasTailCall = false;
214
0
      continue;
215
0
    }
216
2
    if (Feature == "+reference-types") {
217
2
      HasReferenceTypes = true;
218
2
      continue;
219
2
    }
220
0
    if (Feature == "-reference-types") {
221
0
      HasReferenceTypes = false;
222
0
      continue;
223
0
    }
224
225
0
    Diags.Report(diag::err_opt_not_valid_with_opt)
226
0
        << Feature << "-target-feature";
227
0
    return false;
228
0
  }
229
95
  return true;
230
95
}
231
232
94
ArrayRef<Builtin::Info> WebAssemblyTargetInfo::getTargetBuiltins() const {
233
94
  return llvm::makeArrayRef(BuiltinInfo, clang::WebAssembly::LastTSBuiltin -
234
94
                                             Builtin::FirstTSBuiltin);
235
94
}
236
237
void WebAssemblyTargetInfo::adjust(DiagnosticsEngine &Diags,
238
189
                                   LangOptions &Opts) {
239
  // If the Atomics feature isn't available, turn off POSIXThreads and
240
  // ThreadModel, so that we don't predefine _REENTRANT or __STDCPP_THREADS__.
241
189
  if (!HasAtomics) {
242
159
    Opts.POSIXThreads = false;
243
159
    Opts.setThreadModel(LangOptions::ThreadModelKind::Single);
244
159
  }
245
189
}
246
247
void WebAssembly32TargetInfo::getTargetDefines(const LangOptions &Opts,
248
63
                                               MacroBuilder &Builder) const {
249
63
  WebAssemblyTargetInfo::getTargetDefines(Opts, Builder);
250
63
  defineCPUMacros(Builder, "wasm32", /*Tuning=*/false);
251
63
}
252
253
void WebAssembly64TargetInfo::getTargetDefines(const LangOptions &Opts,
254
31
                                               MacroBuilder &Builder) const {
255
31
  WebAssemblyTargetInfo::getTargetDefines(Opts, Builder);
256
31
  defineCPUMacros(Builder, "wasm64", /*Tuning=*/false);
257
31
}