Coverage Report

Created: 2020-02-15 09:57

/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
33
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
1
42
1
  ABI = Name;
43
1
  return true;
44
1
}
45
46
42
bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const {
47
42
  return llvm::StringSwitch<bool>(Feature)
48
42
      .Case("simd128", SIMDLevel >= SIMD128)
49
42
      .Case("unimplemented-simd128", SIMDLevel >= UnimplementedSIMD128)
50
42
      .Case("nontrapping-fptoint", HasNontrappingFPToInt)
51
42
      .Case("sign-ext", HasSignExt)
52
42
      .Case("exception-handling", HasExceptionHandling)
53
42
      .Case("bulk-memory", HasBulkMemory)
54
42
      .Case("atomics", HasAtomics)
55
42
      .Case("mutable-globals", HasMutableGlobals)
56
42
      .Case("multivalue", HasMultivalue)
57
42
      .Case("tail-call", HasTailCall)
58
42
      .Case("reference-types", HasReferenceTypes)
59
42
      .Default(false);
60
42
}
61
62
35
bool WebAssemblyTargetInfo::isValidCPUName(StringRef Name) const {
63
35
  return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames);
64
35
}
65
66
void WebAssemblyTargetInfo::fillValidCPUList(
67
1
    SmallVectorImpl<StringRef> &Values) const {
68
1
  Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
69
1
}
70
71
void WebAssemblyTargetInfo::getTargetDefines(const LangOptions &Opts,
72
71
                                             MacroBuilder &Builder) const {
73
71
  defineCPUMacros(Builder, "wasm", /*Tuning=*/false);
74
71
  if (SIMDLevel >= SIMD128)
75
8
    Builder.defineMacro("__wasm_simd128__");
76
71
  if (SIMDLevel >= UnimplementedSIMD128)
77
4
    Builder.defineMacro("__wasm_unimplemented_simd128__");
78
71
  if (HasNontrappingFPToInt)
79
9
    Builder.defineMacro("__wasm_nontrapping_fptoint__");
80
71
  if (HasSignExt)
81
10
    Builder.defineMacro("__wasm_sign_ext__");
82
71
  if (HasExceptionHandling)
83
8
    Builder.defineMacro("__wasm_exception_handling__");
84
71
  if (HasBulkMemory)
85
13
    Builder.defineMacro("__wasm_bulk_memory__");
86
71
  if (HasAtomics)
87
10
    Builder.defineMacro("__wasm_atomics__");
88
71
  if (HasMutableGlobals)
89
10
    Builder.defineMacro("__wasm_mutable_globals__");
90
71
  if (HasMultivalue)
91
2
    Builder.defineMacro("__wasm_multivalue__");
92
71
  if (HasTailCall)
93
6
    Builder.defineMacro("__wasm_tail_call__");
94
71
  if (HasReferenceTypes)
95
2
    Builder.defineMacro("__wasm_reference_types__");
96
71
}
97
98
void WebAssemblyTargetInfo::setSIMDLevel(llvm::StringMap<bool> &Features,
99
247
                                         SIMDEnum Level) {
100
247
  switch (Level) {
101
156
  case UnimplementedSIMD128:
102
156
    Features["unimplemented-simd128"] = true;
103
156
    LLVM_FALLTHROUGH;
104
160
  case SIMD128:
105
160
    Features["simd128"] = true;
106
160
    LLVM_FALLTHROUGH;
107
247
  case NoSIMD:
108
247
    break;
109
247
  }
110
247
}
111
112
bool WebAssemblyTargetInfo::initFeatureMap(
113
    llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
114
243
    const std::vector<std::string> &FeaturesVec) const {
115
243
  if (CPU == "bleeding-edge") {
116
4
    Features["nontrapping-fptoint"] = true;
117
4
    Features["sign-ext"] = true;
118
4
    Features["bulk-memory"] = true;
119
4
    Features["atomics"] = true;
120
4
    Features["mutable-globals"] = true;
121
4
    Features["tail-call"] = true;
122
4
    setSIMDLevel(Features, SIMD128);
123
4
  }
124
243
  // Other targets do not consider user-configured features here, but while we
125
243
  // are actively developing new features it is useful to let user-configured
126
243
  // features control availability of builtins
127
243
  setSIMDLevel(Features, SIMDLevel);
128
243
  if (HasNontrappingFPToInt)
129
172
    Features["nontrapping-fptoint"] = true;
130
243
  if (HasSignExt)
131
0
    Features["sign-ext"] = true;
132
243
  if (HasExceptionHandling)
133
172
    Features["exception-handling"] = true;
134
243
  if (HasBulkMemory)
135
172
    Features["bulk-memory"] = true;
136
243
  if (HasAtomics)
137
0
    Features["atomics"] = true;
138
243
  if (HasMutableGlobals)
139
0
    Features["mutable-globals"] = true;
140
243
  if (HasMultivalue)
141
0
    Features["multivalue"] = true;
142
243
  if (HasTailCall)
143
0
    Features["tail-call"] = true;
144
243
  if (HasReferenceTypes)
145
0
    Features["reference-types"] = true;
146
243
147
243
  return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
148
243
}
149
150
bool WebAssemblyTargetInfo::handleTargetFeatures(
151
71
    std::vector<std::string> &Features, DiagnosticsEngine &Diags) {
152
80
  for (const auto &Feature : Features) {
153
80
    if (Feature == "+simd128") {
154
4
      SIMDLevel = std::max(SIMDLevel, SIMD128);
155
4
      continue;
156
4
    }
157
76
    if (Feature == "-simd128") {
158
2
      SIMDLevel = std::min(SIMDLevel, SIMDEnum(SIMD128 - 1));
159
2
      continue;
160
2
    }
161
74
    if (Feature == "+unimplemented-simd128") {
162
4
      SIMDLevel = std::max(SIMDLevel, SIMDEnum(UnimplementedSIMD128));
163
4
      continue;
164
4
    }
165
70
    if (Feature == "-unimplemented-simd128") {
166
0
      SIMDLevel = std::min(SIMDLevel, SIMDEnum(UnimplementedSIMD128 - 1));
167
0
      continue;
168
0
    }
169
70
    if (Feature == "+nontrapping-fptoint") {
170
9
      HasNontrappingFPToInt = true;
171
9
      continue;
172
9
    }
173
61
    if (Feature == "-nontrapping-fptoint") {
174
0
      HasNontrappingFPToInt = false;
175
0
      continue;
176
0
    }
177
61
    if (Feature == "+sign-ext") {
178
10
      HasSignExt = true;
179
10
      continue;
180
10
    }
181
51
    if (Feature == "-sign-ext") {
182
0
      HasSignExt = false;
183
0
      continue;
184
0
    }
185
51
    if (Feature == "+exception-handling") {
186
8
      HasExceptionHandling = true;
187
8
      continue;
188
8
    }
189
43
    if (Feature == "-exception-handling") {
190
0
      HasExceptionHandling = false;
191
0
      continue;
192
0
    }
193
43
    if (Feature == "+bulk-memory") {
194
13
      HasBulkMemory = true;
195
13
      continue;
196
13
    }
197
30
    if (Feature == "-bulk-memory") {
198
0
      HasBulkMemory = false;
199
0
      continue;
200
0
    }
201
30
    if (Feature == "+atomics") {
202
10
      HasAtomics = true;
203
10
      continue;
204
10
    }
205
20
    if (Feature == "-atomics") {
206
0
      HasAtomics = false;
207
0
      continue;
208
0
    }
209
20
    if (Feature == "+mutable-globals") {
210
10
      HasMutableGlobals = true;
211
10
      continue;
212
10
    }
213
10
    if (Feature == "-mutable-globals") {
214
0
      HasMutableGlobals = false;
215
0
      continue;
216
0
    }
217
10
    if (Feature == "+multivalue") {
218
2
      HasMultivalue = true;
219
2
      continue;
220
2
    }
221
8
    if (Feature == "-multivalue") {
222
0
      HasMultivalue = false;
223
0
      continue;
224
0
    }
225
8
    if (Feature == "+tail-call") {
226
6
      HasTailCall = true;
227
6
      continue;
228
6
    }
229
2
    if (Feature == "-tail-call") {
230
0
      HasTailCall = false;
231
0
      continue;
232
0
    }
233
2
    if (Feature == "+reference-types") {
234
2
      HasReferenceTypes = true;
235
2
      continue;
236
2
    }
237
0
    if (Feature == "-reference-types") {
238
0
      HasReferenceTypes = false;
239
0
      continue;
240
0
    }
241
0
242
0
    Diags.Report(diag::err_opt_not_valid_with_opt)
243
0
        << Feature << "-target-feature";
244
0
    return false;
245
0
  }
246
71
  return true;
247
71
}
248
249
71
ArrayRef<Builtin::Info> WebAssemblyTargetInfo::getTargetBuiltins() const {
250
71
  return llvm::makeArrayRef(BuiltinInfo, clang::WebAssembly::LastTSBuiltin -
251
71
                                             Builtin::FirstTSBuiltin);
252
71
}
253
254
void WebAssembly32TargetInfo::getTargetDefines(const LangOptions &Opts,
255
41
                                               MacroBuilder &Builder) const {
256
41
  WebAssemblyTargetInfo::getTargetDefines(Opts, Builder);
257
41
  defineCPUMacros(Builder, "wasm32", /*Tuning=*/false);
258
41
}
259
260
void WebAssembly64TargetInfo::getTargetDefines(const LangOptions &Opts,
261
30
                                               MacroBuilder &Builder) const {
262
30
  WebAssemblyTargetInfo::getTargetDefines(Opts, Builder);
263
30
  defineCPUMacros(Builder, "wasm64", /*Tuning=*/false);
264
30
}