clang  10.0.0git
WebAssembly.cpp
Go to the documentation of this file.
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"
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 bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const {
37  return llvm::StringSwitch<bool>(Feature)
38  .Case("simd128", SIMDLevel >= SIMD128)
39  .Case("unimplemented-simd128", SIMDLevel >= UnimplementedSIMD128)
40  .Case("nontrapping-fptoint", HasNontrappingFPToInt)
41  .Case("sign-ext", HasSignExt)
42  .Case("exception-handling", HasExceptionHandling)
43  .Case("bulk-memory", HasBulkMemory)
44  .Case("atomics", HasAtomics)
45  .Case("mutable-globals", HasMutableGlobals)
46  .Case("multivalue", HasMultivalue)
47  .Case("tail-call", HasTailCall)
48  .Default(false);
49 }
50 
51 bool WebAssemblyTargetInfo::isValidCPUName(StringRef Name) const {
52  return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames);
53 }
54 
55 void WebAssemblyTargetInfo::fillValidCPUList(
56  SmallVectorImpl<StringRef> &Values) const {
57  Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
58 }
59 
61  MacroBuilder &Builder) const {
62  defineCPUMacros(Builder, "wasm", /*Tuning=*/false);
63  if (SIMDLevel >= SIMD128)
64  Builder.defineMacro("__wasm_simd128__");
65  if (SIMDLevel >= UnimplementedSIMD128)
66  Builder.defineMacro("__wasm_unimplemented_simd128__");
67  if (HasNontrappingFPToInt)
68  Builder.defineMacro("__wasm_nontrapping_fptoint__");
69  if (HasSignExt)
70  Builder.defineMacro("__wasm_sign_ext__");
71  if (HasExceptionHandling)
72  Builder.defineMacro("__wasm_exception_handling__");
73  if (HasBulkMemory)
74  Builder.defineMacro("__wasm_bulk_memory__");
75  if (HasAtomics)
76  Builder.defineMacro("__wasm_atomics__");
77  if (HasMutableGlobals)
78  Builder.defineMacro("__wasm_mutable_globals__");
79  if (HasMultivalue)
80  Builder.defineMacro("__wasm_multivalue__");
81  if (HasTailCall)
82  Builder.defineMacro("__wasm_tail_call__");
83 }
84 
85 void WebAssemblyTargetInfo::setSIMDLevel(llvm::StringMap<bool> &Features,
86  SIMDEnum Level) {
87  switch (Level) {
88  case UnimplementedSIMD128:
89  Features["unimplemented-simd128"] = true;
90  LLVM_FALLTHROUGH;
91  case SIMD128:
92  Features["simd128"] = true;
93  LLVM_FALLTHROUGH;
94  case NoSIMD:
95  break;
96  }
97 }
98 
99 bool WebAssemblyTargetInfo::initFeatureMap(
100  llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
101  const std::vector<std::string> &FeaturesVec) const {
102  if (CPU == "bleeding-edge") {
103  Features["nontrapping-fptoint"] = true;
104  Features["sign-ext"] = true;
105  Features["atomics"] = true;
106  Features["mutable-globals"] = true;
107  setSIMDLevel(Features, SIMD128);
108  }
109  // Other targets do not consider user-configured features here, but while we
110  // are actively developing new features it is useful to let user-configured
111  // features control availability of builtins
112  setSIMDLevel(Features, SIMDLevel);
113  if (HasNontrappingFPToInt)
114  Features["nontrapping-fptoint"] = true;
115  if (HasSignExt)
116  Features["sign-ext"] = true;
117  if (HasExceptionHandling)
118  Features["exception-handling"] = true;
119  if (HasBulkMemory)
120  Features["bulk-memory"] = true;
121  if (HasAtomics)
122  Features["atomics"] = true;
123  if (HasMutableGlobals)
124  Features["mutable-globals"] = true;
125  if (HasMultivalue)
126  Features["multivalue"] = true;
127  if (HasTailCall)
128  Features["tail-call"] = true;
129 
130  return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
131 }
132 
133 bool WebAssemblyTargetInfo::handleTargetFeatures(
134  std::vector<std::string> &Features, DiagnosticsEngine &Diags) {
135  for (const auto &Feature : Features) {
136  if (Feature == "+simd128") {
137  SIMDLevel = std::max(SIMDLevel, SIMD128);
138  continue;
139  }
140  if (Feature == "-simd128") {
141  SIMDLevel = std::min(SIMDLevel, SIMDEnum(SIMD128 - 1));
142  continue;
143  }
144  if (Feature == "+unimplemented-simd128") {
145  SIMDLevel = std::max(SIMDLevel, SIMDEnum(UnimplementedSIMD128));
146  continue;
147  }
148  if (Feature == "-unimplemented-simd128") {
149  SIMDLevel = std::min(SIMDLevel, SIMDEnum(UnimplementedSIMD128 - 1));
150  continue;
151  }
152  if (Feature == "+nontrapping-fptoint") {
153  HasNontrappingFPToInt = true;
154  continue;
155  }
156  if (Feature == "-nontrapping-fptoint") {
157  HasNontrappingFPToInt = false;
158  continue;
159  }
160  if (Feature == "+sign-ext") {
161  HasSignExt = true;
162  continue;
163  }
164  if (Feature == "-sign-ext") {
165  HasSignExt = false;
166  continue;
167  }
168  if (Feature == "+exception-handling") {
169  HasExceptionHandling = true;
170  continue;
171  }
172  if (Feature == "-exception-handling") {
173  HasExceptionHandling = false;
174  continue;
175  }
176  if (Feature == "+bulk-memory") {
177  HasBulkMemory = true;
178  continue;
179  }
180  if (Feature == "-bulk-memory") {
181  HasBulkMemory = false;
182  continue;
183  }
184  if (Feature == "+atomics") {
185  HasAtomics = true;
186  continue;
187  }
188  if (Feature == "-atomics") {
189  HasAtomics = false;
190  continue;
191  }
192  if (Feature == "+mutable-globals") {
193  HasMutableGlobals = true;
194  continue;
195  }
196  if (Feature == "-mutable-globals") {
197  HasMutableGlobals = false;
198  continue;
199  }
200  if (Feature == "+multivalue") {
201  HasMultivalue = true;
202  continue;
203  }
204  if (Feature == "-multivalue") {
205  HasMultivalue = false;
206  continue;
207  }
208  if (Feature == "+tail-call") {
209  HasTailCall = true;
210  continue;
211  }
212  if (Feature == "-tail-call") {
213  HasTailCall = false;
214  continue;
215  }
216 
217  Diags.Report(diag::err_opt_not_valid_with_opt)
218  << Feature << "-target-feature";
219  return false;
220  }
221  return true;
222 }
223 
224 ArrayRef<Builtin::Info> WebAssemblyTargetInfo::getTargetBuiltins() const {
225  return llvm::makeArrayRef(BuiltinInfo, clang::WebAssembly::LastTSBuiltin -
227 }
228 
230  MacroBuilder &Builder) const {
232  defineCPUMacros(Builder, "wasm32", /*Tuning=*/false);
233 }
234 
236  MacroBuilder &Builder) const {
238  defineCPUMacros(Builder, "wasm64", /*Tuning=*/false);
239 }
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1300
__DEVICE__ int max(int __a, int __b)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:53
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:149
Defines the Diagnostic-related interfaces.
virtual bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeatureVec) const
Initialize the map with the default set of target features for the CPU this should include all legal ...
Definition: TargetInfo.cpp:402
Enumerates target-specific builtins in their own namespaces within namespace clang.
Dataflow Directional Tag Classes.
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods --------------------——===//
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods --------------------——===//
static constexpr llvm::StringLiteral ValidCPUNames[]
Definition: WebAssembly.cpp:33
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods --------------------——===//
Definition: WebAssembly.cpp:60
__DEVICE__ int min(int __a, int __b)
void defineCPUMacros(MacroBuilder &Builder, StringRef CPUName, bool Tuning)
Definition: Targets.cpp:70
void defineMacro(const Twine &Name, const Twine &Value="1")
Append a #define line for macro of the form "\#define Name Value\n".
Definition: MacroBuilder.h:29
Defines enum values for all the target-independent builtin functions.