LLVM 17.0.0git
WebAssemblyAsmPrinter.cpp
Go to the documentation of this file.
1//===-- WebAssemblyAsmPrinter.cpp - WebAssembly LLVM assembly writer ------===//
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/// \file
10/// This file contains a printer that converts from our internal
11/// representation of machine-dependent LLVM code to the WebAssembly assembly
12/// language.
13///
14//===----------------------------------------------------------------------===//
15
22#include "WebAssembly.h"
28#include "llvm/ADT/SmallSet.h"
36#include "llvm/IR/DataLayout.h"
39#include "llvm/IR/Metadata.h"
40#include "llvm/MC/MCContext.h"
42#include "llvm/MC/MCStreamer.h"
43#include "llvm/MC/MCSymbol.h"
46#include "llvm/Support/Debug.h"
48
49using namespace llvm;
50
51#define DEBUG_TYPE "asm-printer"
52
54
55//===----------------------------------------------------------------------===//
56// Helpers.
57//===----------------------------------------------------------------------===//
58
60 const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo();
61 const TargetRegisterClass *TRC = MRI->getRegClass(RegNo);
64 if (TRI->isTypeLegalForClass(*TRC, T))
65 return T;
66 LLVM_DEBUG(errs() << "Unknown type for register number: " << RegNo);
67 llvm_unreachable("Unknown register type");
68 return MVT::Other;
69}
70
72 Register RegNo = MO.getReg();
73 assert(RegNo.isVirtual() &&
74 "Unlowered physical register encountered during assembly printing");
75 assert(!MFI->isVRegStackified(RegNo));
76 unsigned WAReg = MFI->getWAReg(RegNo);
78 return '$' + utostr(WAReg);
79}
80
82 MCTargetStreamer *TS = OutStreamer->getTargetStreamer();
83 return static_cast<WebAssemblyTargetStreamer *>(TS);
84}
85
86// Emscripten exception handling helpers
87//
88// This converts invoke names generated by LowerEmscriptenEHSjLj to real names
89// that are expected by JavaScript glue code. The invoke names generated by
90// Emscripten JS glue code are based on their argument and return types; for
91// example, for a function that takes an i32 and returns nothing, it is
92// 'invoke_vi'. But the format of invoke generated by LowerEmscriptenEHSjLj pass
93// contains a mangled string generated from their IR types, for example,
94// "__invoke_void_%struct.mystruct*_int", because final wasm types are not
95// available in the IR pass. So we convert those names to the form that
96// Emscripten JS code expects.
97//
98// Refer to LowerEmscriptenEHSjLj pass for more details.
99
100// Returns true if the given function name is an invoke name generated by
101// LowerEmscriptenEHSjLj pass.
103 if (Name.front() == '"' && Name.back() == '"')
104 Name = Name.substr(1, Name.size() - 2);
105 return Name.startswith("__invoke_");
106}
107
108// Returns a character that represents the given wasm value type in invoke
109// signatures.
111 switch (VT) {
113 return 'i';
115 return 'j';
117 return 'f';
119 return 'd';
121 return 'V';
123 return 'F';
125 return 'X';
126 }
127 llvm_unreachable("Unhandled wasm::ValType enum");
128}
129
130// Given the wasm signature, generate the invoke name in the format JS glue code
131// expects.
133 assert(Sig->Returns.size() <= 1);
134 std::string Ret = "invoke_";
135 if (!Sig->Returns.empty())
136 for (auto VT : Sig->Returns)
137 Ret += getInvokeSig(VT);
138 else
139 Ret += 'v';
140 // Invokes' first argument is a pointer to the original function, so skip it
141 for (unsigned I = 1, E = Sig->Params.size(); I < E; I++)
142 Ret += getInvokeSig(Sig->Params[I]);
143 return Ret;
144}
145
146//===----------------------------------------------------------------------===//
147// WebAssemblyAsmPrinter Implementation.
148//===----------------------------------------------------------------------===//
149
151 const Function *F, bool EnableEmEH, wasm::WasmSignature *Sig,
152 bool &InvokeDetected) {
153 MCSymbolWasm *WasmSym = nullptr;
154 if (EnableEmEH && isEmscriptenInvokeName(F->getName())) {
155 assert(Sig);
156 InvokeDetected = true;
157 if (Sig->Returns.size() > 1) {
158 std::string Msg =
159 "Emscripten EH/SjLj does not support multivalue returns: " +
160 std::string(F->getName()) + ": " +
163 }
164 WasmSym = cast<MCSymbolWasm>(
166 } else {
167 WasmSym = cast<MCSymbolWasm>(getSymbol(F));
168 }
169 return WasmSym;
170}
171
175 return;
176 }
177
178 assert(!GV->isThreadLocal());
179
180 MCSymbolWasm *Sym = cast<MCSymbolWasm>(getSymbol(GV));
181
182 if (!Sym->getType()) {
184 Type *GlobalVT = GV->getValueType();
185 if (Subtarget) {
186 // Subtarget is only set when a function is defined, because
187 // each function can declare a different subtarget. For example,
188 // on ARM a compilation unit might have a function on ARM and
189 // another on Thumb. Therefore only if Subtarget is non-null we
190 // can actually calculate the legal VTs.
191 const WebAssemblyTargetLowering &TLI = *Subtarget->getTargetLowering();
193 GV->getParent()->getDataLayout(), GlobalVT, VTs);
194 }
195 WebAssembly::wasmSymbolSetType(Sym, GlobalVT, VTs);
196 }
197
198 emitVisibility(Sym, GV->getVisibility(), !GV->isDeclaration());
199 emitSymbolType(Sym);
200 if (GV->hasInitializer()) {
201 assert(getSymbolPreferLocal(*GV) == Sym);
202 emitLinkage(GV, Sym);
203 OutStreamer->emitLabel(Sym);
204 // TODO: Actually emit the initializer value. Otherwise the global has the
205 // default value for its type (0, ref.null, etc).
206 OutStreamer->addBlankLine();
207 }
208}
209
211 auto *WasmSym = cast<MCSymbolWasm>(GetExternalSymbolSymbol(Name));
212
213 // May be called multiple times, so early out.
214 if (WasmSym->getType())
215 return WasmSym;
216
217 const WebAssemblySubtarget &Subtarget = getSubtarget();
218
219 // Except for certain known symbols, all symbols used by CodeGen are
220 // functions. It's OK to hardcode knowledge of specific symbols here; this
221 // method is precisely there for fetching the signatures of known
222 // Clang-provided symbols.
223 if (Name == "__stack_pointer" || Name == "__tls_base" ||
224 Name == "__memory_base" || Name == "__table_base" ||
225 Name == "__tls_size" || Name == "__tls_align") {
226 bool Mutable =
227 Name == "__stack_pointer" || Name == "__tls_base";
228 WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
229 WasmSym->setGlobalType(wasm::WasmGlobalType{
230 uint8_t(Subtarget.hasAddr64() ? wasm::WASM_TYPE_I64
232 Mutable});
233 return WasmSym;
234 }
235
236 if (Name.startswith("GCC_except_table")) {
237 WasmSym->setType(wasm::WASM_SYMBOL_TYPE_DATA);
238 return WasmSym;
239 }
240
243 if (Name == "__cpp_exception" || Name == "__c_longjmp") {
244 WasmSym->setType(wasm::WASM_SYMBOL_TYPE_TAG);
245 // In static linking we define tag symbols in WasmException::endModule().
246 // But we may have multiple objects to be linked together, each of which
247 // defines the tag symbols. To resolve them, we declare them as weak. In
248 // dynamic linking we make tag symbols undefined in the backend, define it
249 // in JS, and feed them to each importing module.
251 WasmSym->setWeak(true);
252 WasmSym->setExternal(true);
253
254 // Currently both C++ exceptions and C longjmps have a single pointer type
255 // param. For C++ exceptions it is a pointer to an exception object, and for
256 // C longjmps it is pointer to a struct that contains a setjmp buffer and a
257 // longjmp return value. We may consider using multiple value parameters for
258 // longjmps later when multivalue support is ready.
259 wasm::ValType AddrType =
261 Params.push_back(AddrType);
262 } else { // Function symbols
263 WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
264 getLibcallSignature(Subtarget, Name, Returns, Params);
265 }
266 auto Signature = std::make_unique<wasm::WasmSignature>(std::move(Returns),
267 std::move(Params));
268 WasmSym->setSignature(Signature.get());
269 addSignature(std::move(Signature));
270
271 return WasmSym;
272}
273
275 std::optional<wasm::WasmSymbolType> WasmTy = Sym->getType();
276 if (!WasmTy)
277 return;
278
279 switch (*WasmTy) {
282 break;
285 break;
288 break;
289 default:
290 break; // We only handle globals, tags and tables here
291 }
292}
293
295 if (signaturesEmitted)
296 return;
297 signaturesEmitted = true;
298
299 // Normally symbols for globals get discovered as the MI gets lowered,
300 // but we need to know about them ahead of time. This will however,
301 // only find symbols that have been used. Unused symbols from globals will
302 // not be found here.
304 for (const auto &Name : MMIW.MachineSymbolsUsed) {
305 auto *WasmSym = cast<MCSymbolWasm>(getOrCreateWasmSymbol(Name.getKey()));
306 if (WasmSym->isFunction()) {
307 // TODO(wvo): is there any case where this overlaps with the call to
308 // emitFunctionType in the loop below?
310 }
311 }
312
313 for (auto &It : OutContext.getSymbols()) {
314 // Emit .globaltype, .tagtype, or .tabletype declarations for extern
315 // declarations, i.e. those that have only been declared (but not defined)
316 // in the current module
317 auto Sym = cast<MCSymbolWasm>(It.getValue());
318 if (!Sym->isDefined())
319 emitSymbolType(Sym);
320 }
321
322 DenseSet<MCSymbol *> InvokeSymbols;
323 for (const auto &F : M) {
324 if (F.isIntrinsic())
325 continue;
326
327 // Emit function type info for all functions. This will emit duplicate
328 // information for defined functions (which already have function type
329 // info emitted alongside their definition), but this is necessary in
330 // order to enable the single-pass WebAssemblyAsmTypeCheck to succeed.
332 SmallVector<MVT, 4> Params;
333 computeSignatureVTs(F.getFunctionType(), &F, F, TM, Params, Results);
334 // At this point these MCSymbols may or may not have been created already
335 // and thus also contain a signature, but we need to get the signature
336 // anyway here in case it is an invoke that has not yet been created. We
337 // will discard it later if it turns out not to be necessary.
338 auto Signature = signatureFromMVTs(Results, Params);
339 bool InvokeDetected = false;
340 auto *Sym = getMCSymbolForFunction(
342 Signature.get(), InvokeDetected);
343
344 // Multiple functions can be mapped to the same invoke symbol. For
345 // example, two IR functions '__invoke_void_i8*' and '__invoke_void_i32'
346 // are both mapped to '__invoke_vi'. We keep them in a set once we emit an
347 // Emscripten EH symbol so we don't emit the same symbol twice.
348 if (InvokeDetected && !InvokeSymbols.insert(Sym).second)
349 continue;
350
352 if (!Sym->getSignature()) {
353 Sym->setSignature(Signature.get());
354 addSignature(std::move(Signature));
355 } else {
356 // This symbol has already been created and had a signature. Discard it.
357 Signature.reset();
358 }
359
361
362 if (F.hasFnAttribute("wasm-import-module")) {
364 F.getFnAttribute("wasm-import-module").getValueAsString();
365 Sym->setImportModule(storeName(Name));
367 }
368 if (F.hasFnAttribute("wasm-import-name")) {
369 // If this is a converted Emscripten EH/SjLj symbol, we shouldn't use
370 // the original function name but the converted symbol name.
372 InvokeDetected
373 ? Sym->getName()
374 : F.getFnAttribute("wasm-import-name").getValueAsString();
375 Sym->setImportName(storeName(Name));
377 }
378
379 if (F.hasFnAttribute("wasm-export-name")) {
380 auto *Sym = cast<MCSymbolWasm>(getSymbol(&F));
381 StringRef Name = F.getFnAttribute("wasm-export-name").getValueAsString();
382 Sym->setExportName(storeName(Name));
384 }
385 }
386}
387
389 // This is required to emit external declarations (like .functypes) when
390 // no functions are defined in the compilation unit and therefore,
391 // emitDecls() is not called until now.
392 emitDecls(M);
393
394 // When a function's address is taken, a TABLE_INDEX relocation is emitted
395 // against the function symbol at the use site. However the relocation
396 // doesn't explicitly refer to the table. In the future we may want to
397 // define a new kind of reloc against both the function and the table, so
398 // that the linker can see that the function symbol keeps the table alive,
399 // but for now manually mark the table as live.
400 for (const auto &F : M) {
401 if (!F.isIntrinsic() && F.hasAddressTaken()) {
402 MCSymbolWasm *FunctionTable =
404 OutStreamer->emitSymbolAttribute(FunctionTable, MCSA_NoDeadStrip);
405 break;
406 }
407 }
408
409 for (const auto &G : M.globals()) {
410 if (!G.hasInitializer() && G.hasExternalLinkage() &&
411 !WebAssembly::isWasmVarAddressSpace(G.getAddressSpace()) &&
412 G.getValueType()->isSized()) {
413 uint16_t Size = M.getDataLayout().getTypeAllocSize(G.getValueType());
414 OutStreamer->emitELFSize(getSymbol(&G),
416 }
417 }
418
419 if (const NamedMDNode *Named = M.getNamedMetadata("wasm.custom_sections")) {
420 for (const Metadata *MD : Named->operands()) {
421 const auto *Tuple = dyn_cast<MDTuple>(MD);
422 if (!Tuple || Tuple->getNumOperands() != 2)
423 continue;
424 const MDString *Name = dyn_cast<MDString>(Tuple->getOperand(0));
425 const MDString *Contents = dyn_cast<MDString>(Tuple->getOperand(1));
426 if (!Name || !Contents)
427 continue;
428
429 OutStreamer->pushSection();
430 std::string SectionName = (".custom_section." + Name->getString()).str();
431 MCSectionWasm *MySection =
433 OutStreamer->switchSection(MySection);
434 OutStreamer->emitBytes(Contents->getString());
435 OutStreamer->popSection();
436 }
437 }
438
441}
442
445 if (const NamedMDNode *Debug = M.getNamedMetadata("llvm.dbg.cu")) {
446 llvm::SmallSet<StringRef, 4> SeenLanguages;
447 for (size_t I = 0, E = Debug->getNumOperands(); I < E; ++I) {
448 const auto *CU = cast<DICompileUnit>(Debug->getOperand(I));
449 StringRef Language = dwarf::LanguageString(CU->getSourceLanguage());
450 Language.consume_front("DW_LANG_");
451 if (SeenLanguages.insert(Language).second)
452 Languages.emplace_back(Language.str(), "");
453 }
454 }
455
457 if (const NamedMDNode *Ident = M.getNamedMetadata("llvm.ident")) {
459 for (size_t I = 0, E = Ident->getNumOperands(); I < E; ++I) {
460 const auto *S = cast<MDString>(Ident->getOperand(I)->getOperand(0));
461 std::pair<StringRef, StringRef> Field = S->getString().split("version");
462 StringRef Name = Field.first.trim();
463 StringRef Version = Field.second.trim();
464 if (SeenTools.insert(Name).second)
465 Tools.emplace_back(Name.str(), Version.str());
466 }
467 }
468
469 int FieldCount = int(!Languages.empty()) + int(!Tools.empty());
470 if (FieldCount != 0) {
472 ".custom_section.producers", SectionKind::getMetadata());
473 OutStreamer->pushSection();
474 OutStreamer->switchSection(Producers);
475 OutStreamer->emitULEB128IntValue(FieldCount);
476 for (auto &Producers : {std::make_pair("language", &Languages),
477 std::make_pair("processed-by", &Tools)}) {
478 if (Producers.second->empty())
479 continue;
480 OutStreamer->emitULEB128IntValue(strlen(Producers.first));
481 OutStreamer->emitBytes(Producers.first);
482 OutStreamer->emitULEB128IntValue(Producers.second->size());
483 for (auto &Producer : *Producers.second) {
484 OutStreamer->emitULEB128IntValue(Producer.first.size());
485 OutStreamer->emitBytes(Producer.first);
486 OutStreamer->emitULEB128IntValue(Producer.second.size());
487 OutStreamer->emitBytes(Producer.second);
488 }
489 }
490 OutStreamer->popSection();
491 }
492}
493
495 struct FeatureEntry {
496 uint8_t Prefix;
497 std::string Name;
498 };
499
500 // Read target features and linkage policies from module metadata
501 SmallVector<FeatureEntry, 4> EmittedFeatures;
502 auto EmitFeature = [&](std::string Feature) {
503 std::string MDKey = (StringRef("wasm-feature-") + Feature).str();
504 Metadata *Policy = M.getModuleFlag(MDKey);
505 if (Policy == nullptr)
506 return;
507
508 FeatureEntry Entry;
509 Entry.Prefix = 0;
510 Entry.Name = Feature;
511
512 if (auto *MD = cast<ConstantAsMetadata>(Policy))
513 if (auto *I = cast<ConstantInt>(MD->getValue()))
514 Entry.Prefix = I->getZExtValue();
515
516 // Silently ignore invalid metadata
517 if (Entry.Prefix != wasm::WASM_FEATURE_PREFIX_USED &&
518 Entry.Prefix != wasm::WASM_FEATURE_PREFIX_REQUIRED &&
520 return;
521
522 EmittedFeatures.push_back(Entry);
523 };
524
525 for (const SubtargetFeatureKV &KV : WebAssemblyFeatureKV) {
526 EmitFeature(KV.Key);
527 }
528 // This pseudo-feature tells the linker whether shared memory would be safe
529 EmitFeature("shared-mem");
530
531 // This is an "architecture", not a "feature", but we emit it as such for
532 // the benefit of tools like Binaryen and consistency with other producers.
533 // FIXME: Subtarget is null here, so can't Subtarget->hasAddr64() ?
534 if (M.getDataLayout().getPointerSize() == 8) {
535 // Can't use EmitFeature since "wasm-feature-memory64" is not a module
536 // flag.
537 EmittedFeatures.push_back({wasm::WASM_FEATURE_PREFIX_USED, "memory64"});
538 }
539
540 if (EmittedFeatures.size() == 0)
541 return;
542
543 // Emit features and linkage policies into the "target_features" section
544 MCSectionWasm *FeaturesSection = OutContext.getWasmSection(
545 ".custom_section.target_features", SectionKind::getMetadata());
546 OutStreamer->pushSection();
547 OutStreamer->switchSection(FeaturesSection);
548
549 OutStreamer->emitULEB128IntValue(EmittedFeatures.size());
550 for (auto &F : EmittedFeatures) {
551 OutStreamer->emitIntValue(F.Prefix, 1);
552 OutStreamer->emitULEB128IntValue(F.Name.size());
553 OutStreamer->emitBytes(F.Name);
554 }
555
556 OutStreamer->popSection();
557}
558
561 assert(MF->getConstantPool()->getConstants().empty() &&
562 "WebAssembly disables constant pools");
563}
564
566 // Nothing to do; jump tables are incorporated into the instruction stream.
567}
568
570 const Function &F = MF->getFunction();
571 SmallVector<MVT, 1> ResultVTs;
572 SmallVector<MVT, 4> ParamVTs;
573 computeSignatureVTs(F.getFunctionType(), &F, F, TM, ParamVTs, ResultVTs);
574
575 auto Signature = signatureFromMVTs(ResultVTs, ParamVTs);
576 auto *WasmSym = cast<MCSymbolWasm>(CurrentFnSym);
577 WasmSym->setSignature(Signature.get());
578 addSignature(std::move(Signature));
579 WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
580
582
583 // Emit the function index.
584 if (MDNode *Idx = F.getMetadata("wasm.index")) {
585 assert(Idx->getNumOperands() == 1);
586
588 cast<ConstantAsMetadata>(Idx->getOperand(0))->getValue()));
589 }
590
592 valTypesFromMVTs(MFI->getLocals(), Locals);
593 getTargetStreamer()->emitLocal(Locals);
594
596}
597
599 LLVM_DEBUG(dbgs() << "EmitInstruction: " << *MI << '\n');
600 WebAssembly_MC::verifyInstructionPredicates(MI->getOpcode(),
601 Subtarget->getFeatureBits());
602
603 switch (MI->getOpcode()) {
604 case WebAssembly::ARGUMENT_i32:
605 case WebAssembly::ARGUMENT_i32_S:
606 case WebAssembly::ARGUMENT_i64:
607 case WebAssembly::ARGUMENT_i64_S:
608 case WebAssembly::ARGUMENT_f32:
609 case WebAssembly::ARGUMENT_f32_S:
610 case WebAssembly::ARGUMENT_f64:
611 case WebAssembly::ARGUMENT_f64_S:
612 case WebAssembly::ARGUMENT_v16i8:
613 case WebAssembly::ARGUMENT_v16i8_S:
614 case WebAssembly::ARGUMENT_v8i16:
615 case WebAssembly::ARGUMENT_v8i16_S:
616 case WebAssembly::ARGUMENT_v4i32:
617 case WebAssembly::ARGUMENT_v4i32_S:
618 case WebAssembly::ARGUMENT_v2i64:
619 case WebAssembly::ARGUMENT_v2i64_S:
620 case WebAssembly::ARGUMENT_v4f32:
621 case WebAssembly::ARGUMENT_v4f32_S:
622 case WebAssembly::ARGUMENT_v2f64:
623 case WebAssembly::ARGUMENT_v2f64_S:
624 // These represent values which are live into the function entry, so there's
625 // no instruction to emit.
626 break;
627 case WebAssembly::FALLTHROUGH_RETURN: {
628 // These instructions represent the implicit return at the end of a
629 // function body.
630 if (isVerbose()) {
631 OutStreamer->AddComment("fallthrough-return");
632 OutStreamer->addBlankLine();
633 }
634 break;
635 }
636 case WebAssembly::COMPILER_FENCE:
637 // This is a compiler barrier that prevents instruction reordering during
638 // backend compilation, and should not be emitted.
639 break;
640 default: {
641 WebAssemblyMCInstLower MCInstLowering(OutContext, *this);
642 MCInst TmpInst;
643 MCInstLowering.lower(MI, TmpInst);
644 EmitToStreamer(*OutStreamer, TmpInst);
645 break;
646 }
647 }
648}
649
651 unsigned OpNo,
652 const char *ExtraCode,
653 raw_ostream &OS) {
654 // First try the generic code, which knows about modifiers like 'c' and 'n'.
655 if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS))
656 return false;
657
658 if (!ExtraCode) {
659 const MachineOperand &MO = MI->getOperand(OpNo);
660 switch (MO.getType()) {
662 OS << MO.getImm();
663 return false;
665 // FIXME: only opcode that still contains registers, as required by
666 // MachineInstr::getDebugVariable().
667 assert(MI->getOpcode() == WebAssembly::INLINEASM);
668 OS << regToString(MO);
669 return false;
672 return false;
675 printOffset(MO.getOffset(), OS);
676 return false;
678 MO.getMBB()->getSymbol()->print(OS, MAI);
679 return false;
680 default:
681 break;
682 }
683 }
684
685 return true;
686}
687
689 unsigned OpNo,
690 const char *ExtraCode,
691 raw_ostream &OS) {
692 // The current approach to inline asm is that "r" constraints are expressed
693 // as local indices, rather than values on the operand stack. This simplifies
694 // using "r" as it eliminates the need to push and pop the values in a
695 // particular order, however it also makes it impossible to have an "m"
696 // constraint. So we don't support it.
697
698 return AsmPrinter::PrintAsmMemoryOperand(MI, OpNo, ExtraCode, OS);
699}
700
701// Force static initialization.
705}
Function Alias Analysis Results
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:127
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
#define LLVM_DEBUG(X)
Definition: Debug.h:101
std::string Name
uint64_t Size
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
unsigned const TargetRegisterInfo * TRI
This file contains the declarations for metadata subclasses.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the SmallSet class.
This file contains some functions that are useful when dealing with strings.
static std::string getEmscriptenInvokeSymbolName(wasm::WasmSignature *Sig)
static bool isEmscriptenInvokeName(StringRef Name)
static char getInvokeSig(wasm::ValType VT)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyAsmPrinter()
cl::opt< bool > WasmKeepRegisters
This file declares the class to lower WebAssembly MachineInstrs to their corresponding MCInst records...
This file provides WebAssembly-specific target descriptions.
This file declares WebAssembly-specific per-machine-function information.
This file contains the WebAssembly implementation of the WebAssemblyRegisterInfo class.
This file provides signature information for runtime libcalls.
This file registers the WebAssembly target.
This file declares the WebAssembly-specific subclass of TargetMachine.
This file declares WebAssembly-specific target streamer classes.
This file contains the declaration of the WebAssembly-specific type parsing utility functions.
This file contains the declaration of the WebAssembly-specific utility functions.
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end.
MCSymbol * getSymbol(const GlobalValue *GV) const
Definition: AsmPrinter.cpp:662
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:398
virtual void emitGlobalVariable(const GlobalVariable *GV)
Emit the specified global variable to the .s file.
Definition: AsmPrinter.cpp:684
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:87
virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS)
Print the MachineOperand as a symbol.
const MCAsmInfo * MAI
Target Asm Printer information.
Definition: AsmPrinter.h:90
MachineFunction * MF
The current machine function.
Definition: AsmPrinter.h:102
virtual void emitFunctionBodyStart()
Targets can override this to emit stuff before the first basic block in the function.
Definition: AsmPrinter.h:555
virtual void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const
This emits linkage information about GVSym based on GV, if this is supported by the target.
Definition: AsmPrinter.cpp:617
void printOffset(int64_t Offset, raw_ostream &OS) const
This is just convenient handler for printing offsets.
MCSymbol * getSymbolPreferLocal(const GlobalValue &GV) const
Similar to getSymbol() but preferred for references.
Definition: AsmPrinter.cpp:666
MCSymbol * CurrentFnSym
The symbol for the current function.
Definition: AsmPrinter.h:121
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
Definition: AsmPrinter.h:105
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition: AsmPrinter.h:94
MCSymbol * GetExternalSymbolSymbol(StringRef Sym) const
Return the MCSymbol for the specified ExternalSymbol.
bool isPositionIndependent() const
Definition: AsmPrinter.cpp:370
void emitVisibility(MCSymbol *Sym, unsigned Visibility, bool IsDefinition=true) const
This emits visibility information about symbol, if this is supported by the target.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:99
virtual const MCExpr * lowerConstant(const Constant *CV)
Lower the specified LLVM Constant to an MCExpr.
virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
bool isVerbose() const
Return true if assembly output should contain comments.
Definition: AsmPrinter.h:269
@ Debug
Emit .debug_frame.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
Implements a dense probed hash-table based set.
Definition: DenseSet.h:271
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
Definition: GlobalValue.h:259
VisibilityTypes getVisibility() const
Definition: GlobalValue.h:244
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:275
unsigned getAddressSpace() const
Definition: GlobalValue.h:201
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:652
Type * getValueType() const
Definition: GlobalValue.h:292
bool hasInitializer() const
Definitions have initializers, declarations don't.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
MCSectionWasm * getWasmSection(const Twine &Section, SectionKind K, unsigned Flags=0)
Definition: MCContext.h:644
const SymbolTable & getSymbols() const
getSymbols - Get a reference for the symbol table for clients that want to, for example,...
Definition: MCContext.h:525
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
This represents a section on wasm.
Definition: MCSectionWasm.h:26
std::optional< wasm::WasmSymbolType > getType() const
Definition: MCSymbolWasm.h:51
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:58
Target specific streamer interface.
Definition: MCStreamer.h:93
Metadata node.
Definition: Metadata.h:943
A single uniqued string.
Definition: Metadata.h:611
StringRef getString() const
Definition: Metadata.cpp:507
Machine Value Type.
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
const std::vector< MachineConstantPoolEntry > & getConstants() const
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
Representation of each machine instruction.
Definition: MachineInstr.h:68
MachineModuleInfoWasm - This is a MachineModuleInfoImpl implementation for Wasm targets.
const Module * getModule() const
Ty & getObjFileInfo()
Keep track of various per-module pieces of information for backends that would like to do so.
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
MachineBasicBlock * getMBB() const
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
const char * getSymbolName() const
Register getReg() const
getReg - Returns the register number.
@ MO_Immediate
Immediate operand.
@ MO_GlobalAddress
Address of a global value.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
@ MO_ExternalSymbol
Name of external global symbol.
int64_t getOffset() const
Return the offset from the symbol in this operand.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
Root of the metadata hierarchy.
Definition: Metadata.h:61
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
LLVMContext & getContext() const
Get the global data context.
Definition: Module.h:262
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.cpp:398
A tuple of MDNodes.
Definition: Metadata.h:1587
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:91
static SectionKind getMetadata()
Definition: SectionKind.h:188
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:135
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:179
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:941
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
void emitJumpTableInfo() override
Print assembly representations of the jump tables used by the current function to the current output ...
void emitGlobalVariable(const GlobalVariable *GV) override
Emit the specified global variable to the .s file.
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
const WebAssemblySubtarget & getSubtarget() const
WebAssemblyTargetStreamer * getTargetStreamer()
void emitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
std::string regToString(const MachineOperand &MO)
void emitSymbolType(const MCSymbolWasm *Sym)
MCSymbol * getOrCreateWasmSymbol(StringRef Name)
void emitConstantPool() override
Print to the current output stream assembly representations of the constants in the constant pool MCP...
MVT getRegType(unsigned RegNo) const
void emitFunctionBodyStart() override
Targets can override this to emit stuff before the first basic block in the function.
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
MCSymbolWasm * getMCSymbolForFunction(const Function *F, bool EnableEmEH, wasm::WasmSignature *Sig, bool &InvokeDetected)
void addSignature(std::unique_ptr< wasm::WasmSignature > &&Sig)
void emitEndOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the end of their file...
unsigned getWAReg(unsigned VReg) const
const std::vector< MVT > & getLocals() const
This class is used to lower an MachineInstr into an MCInst.
void lower(const MachineInstr *MI, MCInst &OutMI) const
const WebAssemblyTargetLowering * getTargetLowering() const override
const WebAssemblyRegisterInfo * getRegisterInfo() const override
WebAssembly-specific streamer interface, to implement support WebAssembly-specific assembly directive...
virtual void emitFunctionType(const MCSymbolWasm *Sym)=0
.functype
virtual void emitLocal(ArrayRef< wasm::ValType > Types)=0
.local
virtual void emitTagType(const MCSymbolWasm *Sym)=0
.tagtype
virtual void emitExportName(const MCSymbolWasm *Sym, StringRef ExportName)=0
.export_name
virtual void emitGlobalType(const MCSymbolWasm *Sym)=0
.globaltype
virtual void emitImportModule(const MCSymbolWasm *Sym, StringRef ImportModule)=0
.import_module
virtual void emitTableType(const MCSymbolWasm *Sym)=0
.tabletype
virtual void emitImportName(const MCSymbolWasm *Sym, StringRef ImportName)=0
.import_name
virtual void emitIndIdx(const MCExpr *Value)=0
.indidx
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
StringRef LanguageString(unsigned Language)
Definition: Dwarf.cpp:327
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MCSymbolWasm * getOrCreateFunctionTableSymbol(MCContext &Ctx, const WebAssemblySubtarget *Subtarget)
Returns the __indirect_function_table, for use in call_indirect and in function bitcasts.
cl::opt< bool > WasmEnableEmEH
cl::opt< bool > WasmEnableEmSjLj
std::string signatureToString(const wasm::WasmSignature *Sig)
void wasmSymbolSetType(MCSymbolWasm *Sym, const Type *GlobalVT, const ArrayRef< MVT > &VTs)
Sets a Wasm Symbol Type.
bool isWasmVarAddressSpace(unsigned AS)
@ WASM_FEATURE_PREFIX_USED
Definition: Wasm.h:344
@ WASM_FEATURE_PREFIX_REQUIRED
Definition: Wasm.h:345
@ WASM_FEATURE_PREFIX_DISALLOWED
Definition: Wasm.h:346
@ WASM_SYMBOL_TYPE_GLOBAL
Definition: Wasm.h:385
@ WASM_SYMBOL_TYPE_DATA
Definition: Wasm.h:384
@ WASM_SYMBOL_TYPE_TAG
Definition: Wasm.h:387
@ WASM_SYMBOL_TYPE_TABLE
Definition: Wasm.h:388
@ WASM_SYMBOL_TYPE_FUNCTION
Definition: Wasm.h:383
@ WASM_TYPE_I64
Definition: Wasm.h:262
@ WASM_TYPE_I32
Definition: Wasm.h:261
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void computeSignatureVTs(const FunctionType *Ty, const Function *TargetFunc, const Function &ContextFunc, const TargetMachine &TM, SmallVectorImpl< MVT > &Params, SmallVectorImpl< MVT > &Results)
const SubtargetFeatureKV WebAssemblyFeatureKV[WebAssembly::NumSubtargetFeatures]
void valTypesFromMVTs(const ArrayRef< MVT > &In, SmallVectorImpl< wasm::ValType > &Out)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
Target & getTheWebAssemblyTarget32()
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
std::unique_ptr< wasm::WasmSignature > signatureFromMVTs(const SmallVectorImpl< MVT > &Results, const SmallVectorImpl< MVT > &Params)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Target & getTheWebAssemblyTarget64()
void getLibcallSignature(const WebAssemblySubtarget &Subtarget, RTLIB::Libcall LC, SmallVectorImpl< wasm::ValType > &Rets, SmallVectorImpl< wasm::ValType > &Params)
void computeLegalValueVTs(const WebAssemblyTargetLowering &TLI, LLVMContext &Ctx, const DataLayout &DL, Type *Ty, SmallVectorImpl< MVT > &ValueVTs)
@ MCSA_NoDeadStrip
.no_dead_strip (MachO)
Definition: MCDirectives.h:39
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...
Used to provide key value pairs for feature and CPU bit flags.
SmallVector< ValType, 1 > Returns
Definition: Wasm.h:435
SmallVector< ValType, 4 > Params
Definition: Wasm.h:436