Coverage Report

Created: 2020-09-22 08:39

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