Coverage Report

Created: 2022-07-16 07:03

/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
107
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
40
bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const {
47
40
  return llvm::StringSwitch<bool>(Feature)
48
40
      .Case("simd128", SIMDLevel >= SIMD128)
49
40
      .Case("relaxed-simd", SIMDLevel >= RelaxedSIMD)
50
40
      .Case("nontrapping-fptoint", HasNontrappingFPToInt)
51
40
      .Case("sign-ext", HasSignExt)
52
40
      .Case("exception-handling", HasExceptionHandling)
53
40
      .Case("bulk-memory", HasBulkMemory)
54
40
      .Case("atomics", HasAtomics)
55
40
      .Case("mutable-globals", HasMutableGlobals)
56
40
      .Case("multivalue", HasMultivalue)
57
40
      .Case("tail-call", HasTailCall)
58
40
      .Case("reference-types", HasReferenceTypes)
59
40
      .Case("extended-const", HasExtendedConst)
60
40
      .Default(false);
61
40
}
62
63
55
bool WebAssemblyTargetInfo::isValidCPUName(StringRef Name) const {
64
55
  return llvm::is_contained(ValidCPUNames, Name);
65
55
}
66
67
void WebAssemblyTargetInfo::fillValidCPUList(
68
1
    SmallVectorImpl<StringRef> &Values) const {
69
1
  Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
70
1
}
71
72
void WebAssemblyTargetInfo::getTargetDefines(const LangOptions &Opts,
73
114
                                             MacroBuilder &Builder) const {
74
114
  defineCPUMacros(Builder, "wasm", /*Tuning=*/false);
75
114
  if (SIMDLevel >= SIMD128)
76
9
    Builder.defineMacro("__wasm_simd128__");
77
114
  if (SIMDLevel >= RelaxedSIMD)
78
4
    Builder.defineMacro("__wasm_relaxed_simd__");
79
114
  if (HasNontrappingFPToInt)
80
9
    Builder.defineMacro("__wasm_nontrapping_fptoint__");
81
114
  if (HasSignExt)
82
10
    Builder.defineMacro("__wasm_sign_ext__");
83
114
  if (HasExceptionHandling)
84
5
    Builder.defineMacro("__wasm_exception_handling__");
85
114
  if (HasBulkMemory)
86
19
    Builder.defineMacro("__wasm_bulk_memory__");
87
114
  if (HasAtomics)
88
19
    Builder.defineMacro("__wasm_atomics__");
89
114
  if (HasMutableGlobals)
90
10
    Builder.defineMacro("__wasm_mutable_globals__");
91
114
  if (HasMultivalue)
92
2
    Builder.defineMacro("__wasm_multivalue__");
93
114
  if (HasTailCall)
94
6
    Builder.defineMacro("__wasm_tail_call__");
95
114
  if (HasReferenceTypes)
96
2
    Builder.defineMacro("__wasm_reference_types__");
97
114
  if (HasExtendedConst)
98
2
    Builder.defineMacro("__wasm_extended_const__");
99
114
}
100
101
void WebAssemblyTargetInfo::setSIMDLevel(llvm::StringMap<bool> &Features,
102
15
                                         SIMDEnum Level, bool Enabled) {
103
15
  if (Enabled) {
104
13
    switch (Level) {
105
4
    case RelaxedSIMD:
106
4
      Features["relaxed-simd"] = true;
107
4
      LLVM_FALLTHROUGH;
108
13
    case SIMD128:
109
13
      Features["simd128"] = true;
110
13
      LLVM_FALLTHROUGH;
111
13
    case NoSIMD:
112
13
      break;
113
13
    }
114
13
    return;
115
13
  }
116
117
2
  switch (Level) {
118
0
  case NoSIMD:
119
2
  case SIMD128:
120
2
    Features["simd128"] = false;
121
2
    LLVM_FALLTHROUGH;
122
2
  case RelaxedSIMD:
123
2
    Features["relaxed-simd"] = false;
124
2
    break;
125
2
  }
126
2
}
127
128
void WebAssemblyTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
129
                                              StringRef Name,
130
71
                                              bool Enabled) const {
131
71
  if (Name == "simd128")
132
7
    setSIMDLevel(Features, SIMD128, Enabled);
133
64
  else if (Name == "relaxed-simd")
134
4
    setSIMDLevel(Features, RelaxedSIMD, Enabled);
135
60
  else
136
60
    Features[Name] = Enabled;
137
71
}
138
139
bool WebAssemblyTargetInfo::initFeatureMap(
140
    llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
141
114
    const std::vector<std::string> &FeaturesVec) const {
142
114
  if (CPU == "bleeding-edge") {
143
4
    Features["nontrapping-fptoint"] = true;
144
4
    Features["sign-ext"] = true;
145
4
    Features["bulk-memory"] = true;
146
4
    Features["atomics"] = true;
147
4
    Features["mutable-globals"] = true;
148
4
    Features["tail-call"] = true;
149
4
    setSIMDLevel(Features, SIMD128, true);
150
4
  }
151
152
114
  return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
153
114
}
154
155
bool WebAssemblyTargetInfo::handleTargetFeatures(
156
114
    std::vector<std::string> &Features, DiagnosticsEngine &Diags) {
157
114
  for (const auto &Feature : Features) {
158
101
    if (Feature == "+simd128") {
159
9
      SIMDLevel = std::max(SIMDLevel, SIMD128);
160
9
      continue;
161
9
    }
162
92
    if (Feature == "-simd128") {
163
2
      SIMDLevel = std::min(SIMDLevel, SIMDEnum(SIMD128 - 1));
164
2
      continue;
165
2
    }
166
90
    if (Feature == "+relaxed-simd") {
167
4
      SIMDLevel = std::max(SIMDLevel, RelaxedSIMD);
168
4
      continue;
169
4
    }
170
86
    if (Feature == "-relaxed-simd") {
171
2
      SIMDLevel = std::min(SIMDLevel, SIMDEnum(RelaxedSIMD - 1));
172
2
      continue;
173
2
    }
174
84
    if (Feature == "+nontrapping-fptoint") {
175
9
      HasNontrappingFPToInt = true;
176
9
      continue;
177
9
    }
178
75
    if (Feature == "-nontrapping-fptoint") {
179
0
      HasNontrappingFPToInt = false;
180
0
      continue;
181
0
    }
182
75
    if (Feature == "+sign-ext") {
183
10
      HasSignExt = true;
184
10
      continue;
185
10
    }
186
65
    if (Feature == "-sign-ext") {
187
0
      HasSignExt = false;
188
0
      continue;
189
0
    }
190
65
    if (Feature == "+exception-handling") {
191
5
      HasExceptionHandling = true;
192
5
      continue;
193
5
    }
194
60
    if (Feature == "-exception-handling") {
195
0
      HasExceptionHandling = false;
196
0
      continue;
197
0
    }
198
60
    if (Feature == "+bulk-memory") {
199
19
      HasBulkMemory = true;
200
19
      continue;
201
19
    }
202
41
    if (Feature == "-bulk-memory") {
203
0
      HasBulkMemory = false;
204
0
      continue;
205
0
    }
206
41
    if (Feature == "+atomics") {
207
19
      HasAtomics = true;
208
19
      continue;
209
19
    }
210
22
    if (Feature == "-atomics") {
211
0
      HasAtomics = false;
212
0
      continue;
213
0
    }
214
22
    if (Feature == "+mutable-globals") {
215
10
      HasMutableGlobals = true;
216
10
      continue;
217
10
    }
218
12
    if (Feature == "-mutable-globals") {
219
0
      HasMutableGlobals = false;
220
0
      continue;
221
0
    }
222
12
    if (Feature == "+multivalue") {
223
2
      HasMultivalue = true;
224
2
      continue;
225
2
    }
226
10
    if (Feature == "-multivalue") {
227
0
      HasMultivalue = false;
228
0
      continue;
229
0
    }
230
10
    if (Feature == "+tail-call") {
231
6
      HasTailCall = true;
232
6
      continue;
233
6
    }
234
4
    if (Feature == "-tail-call") {
235
0
      HasTailCall = false;
236
0
      continue;
237
0
    }
238
4
    if (Feature == "+reference-types") {
239
2
      HasReferenceTypes = true;
240
2
      continue;
241
2
    }
242
2
    if (Feature == "-reference-types") {
243
0
      HasReferenceTypes = false;
244
0
      continue;
245
0
    }
246
2
    if (Feature == "+extended-const") {
247
2
      HasExtendedConst = true;
248
2
      continue;
249
2
    }
250
0
    if (Feature == "-extended-const") {
251
0
      HasExtendedConst = false;
252
0
      continue;
253
0
    }
254
255
0
    Diags.Report(diag::err_opt_not_valid_with_opt)
256
0
        << Feature << "-target-feature";
257
0
    return false;
258
0
  }
259
114
  return true;
260
114
}
261
262
114
ArrayRef<Builtin::Info> WebAssemblyTargetInfo::getTargetBuiltins() const {
263
114
  return llvm::makeArrayRef(BuiltinInfo, clang::WebAssembly::LastTSBuiltin -
264
114
                                             Builtin::FirstTSBuiltin);
265
114
}
266
267
void WebAssemblyTargetInfo::adjust(DiagnosticsEngine &Diags,
268
228
                                   LangOptions &Opts) {
269
228
  TargetInfo::adjust(Diags, Opts);
270
  // Turn off POSIXThreads and ThreadModel so that we don't predefine _REENTRANT
271
  // or __STDCPP_THREADS__ if we will eventually end up stripping atomics
272
  // because they are unsupported.
273
228
  if (!HasAtomics || 
!HasBulkMemory38
) {
274
198
    Opts.POSIXThreads = false;
275
198
    Opts.setThreadModel(LangOptions::ThreadModelKind::Single);
276
198
    Opts.ThreadsafeStatics = false;
277
198
  }
278
228
}
279
280
void WebAssembly32TargetInfo::getTargetDefines(const LangOptions &Opts,
281
71
                                               MacroBuilder &Builder) const {
282
71
  WebAssemblyTargetInfo::getTargetDefines(Opts, Builder);
283
71
  defineCPUMacros(Builder, "wasm32", /*Tuning=*/false);
284
71
}
285
286
void WebAssembly64TargetInfo::getTargetDefines(const LangOptions &Opts,
287
43
                                               MacroBuilder &Builder) const {
288
43
  WebAssemblyTargetInfo::getTargetDefines(Opts, Builder);
289
43
  defineCPUMacros(Builder, "wasm64", /*Tuning=*/false);
290
43
}