1//===- WebAssemblyTargetMachine.cpp - Define TargetMachine for WebAssembly -==//
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 defines the WebAssembly-specific subclass of TargetMachine.
11///
12//===----------------------------------------------------------------------===//
13
14#include "WebAssemblyTargetMachine.h"
15#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
16#include "TargetInfo/WebAssemblyTargetInfo.h"
17#include "WebAssembly.h"
18#include "WebAssemblyISelLowering.h"
19#include "WebAssemblyMachineFunctionInfo.h"
20#include "WebAssemblyTargetObjectFile.h"
21#include "WebAssemblyTargetTransformInfo.h"
22#include "WebAssemblyUtilities.h"
23#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
24#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
25#include "llvm/CodeGen/GlobalISel/Legalizer.h"
26#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
27#include "llvm/CodeGen/MIRParser/MIParser.h"
28#include "llvm/CodeGen/Passes.h"
29#include "llvm/CodeGen/RegAllocRegistry.h"
30#include "llvm/CodeGen/TargetPassConfig.h"
31#include "llvm/IR/Function.h"
32#include "llvm/InitializePasses.h"
33#include "llvm/MC/TargetRegistry.h"
34#include "llvm/Support/Compiler.h"
35#include "llvm/Target/TargetOptions.h"
36#include "llvm/Transforms/Scalar.h"
37#include "llvm/Transforms/Utils.h"
38#include <optional>
39using namespace llvm;
40
41#define DEBUG_TYPE "wasm"
42
43// A command-line option to keep implicit locals
44// for the purpose of testing with lit/llc ONLY.
45// This produces output which is not valid WebAssembly, and is not supported
46// by assemblers/disassemblers and other MC based tools.
47cl::opt<bool> WebAssembly::WasmDisableExplicitLocals(
48 "wasm-disable-explicit-locals", cl::Hidden,
49 cl::desc("WebAssembly: output implicit locals in"
50 " instruction output for test purposes only."),
51 cl::init(Val: false));
52
53// Exception handling & setjmp-longjmp handling related options.
54
55// Emscripten's asm.js-style setjmp/longjmp handling
56cl::opt<bool> WebAssembly::WasmEnableEmSjLj(
57 "enable-emscripten-sjlj",
58 cl::desc("WebAssembly Emscripten-style setjmp/longjmp handling"),
59 cl::init(Val: false));
60// setjmp/longjmp handling using wasm EH instructions
61cl::opt<bool> WebAssembly::WasmEnableSjLj(
62 "wasm-enable-sjlj", cl::desc("WebAssembly setjmp/longjmp handling"));
63// If true, use the legacy Wasm EH proposal:
64// https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/legacy/Exceptions.md
65// And if false, use the standardized Wasm EH proposal:
66// https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md
67// Currently set to true by default because not all major web browsers turn on
68// the new standard proposal by default, but will later change to false.
69cl::opt<bool> WebAssembly::WasmUseLegacyEH(
70 "wasm-use-legacy-eh", cl::desc("WebAssembly exception handling (legacy)"),
71 cl::init(Val: true));
72
73extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
74LLVMInitializeWebAssemblyTarget() {
75 // Register the target.
76 RegisterTargetMachine<WebAssemblyTargetMachine> X(
77 getTheWebAssemblyTarget32());
78 RegisterTargetMachine<WebAssemblyTargetMachine> Y(
79 getTheWebAssemblyTarget64());
80
81 // Register backend passes
82 auto &PR = *PassRegistry::getPassRegistry();
83 initializeGlobalISel(PR);
84 initializeWebAssemblyPreLegalizerCombinerLegacyPass(PR);
85 initializeWebAssemblyPostLegalizerCombinerLegacyPass(PR);
86 initializeWebAssemblyAddMissingPrototypesLegacyPass(PR);
87 initializeWebAssemblyLowerEmscriptenEHSjLjLegacyPass(PR);
88 initializeLowerGlobalDtorsLegacyPassPass(PR);
89 initializeWebAssemblyFixFunctionBitcastsLegacyPass(PR);
90 initializeWebAssemblyOptimizeReturnedLegacyPass(PR);
91 initializeWebAssemblyRefTypeMem2LocalLegacyPass(PR);
92 initializeWebAssemblyArgumentMoveLegacyPass(PR);
93 initializeWebAssemblyAsmPrinterPass(PR);
94 initializeWebAssemblySetP2AlignOperandsLegacyPass(PR);
95 initializeWebAssemblyReplacePhysRegsLegacyPass(PR);
96 initializeWebAssemblyOptimizeLiveIntervalsLegacyPass(PR);
97 initializeWebAssemblyMemIntrinsicResultsLegacyPass(PR);
98 initializeWebAssemblyRegStackifyLegacyPass(PR);
99 initializeWebAssemblyRegColoringLegacyPass(PR);
100 initializeWebAssemblyNullifyDebugValueListsLegacyPass(PR);
101 initializeWebAssemblyFixIrreducibleControlFlowLegacyPass(PR);
102 initializeWebAssemblyLateEHPrepareLegacyPass(PR);
103 initializeWebAssemblyExceptionInfoWrapperPassPass(PR);
104 initializeWebAssemblyCFGSortLegacyPass(PR);
105 initializeWebAssemblyCFGStackifyLegacyPass(PR);
106 initializeWebAssemblyExplicitLocalsLegacyPass(PR);
107 initializeWebAssemblyLowerBrUnlessLegacyPass(PR);
108 initializeWebAssemblyRegNumberingLegacyPass(PR);
109 initializeWebAssemblyDebugFixupLegacyPass(PR);
110 initializeWebAssemblyPeepholeLegacyPass(PR);
111 initializeWebAssemblyMCLowerPreLegacyPass(PR);
112 initializeWebAssemblyFixBrTableDefaultsLegacyPass(PR);
113 initializeWebAssemblyDAGToDAGISelLegacyPass(PR);
114}
115
116//===----------------------------------------------------------------------===//
117// WebAssembly Lowering public interface.
118//===----------------------------------------------------------------------===//
119
120static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) {
121 // Default to static relocation model. This should always be more optimal
122 // than PIC since the static linker can determine all global addresses and
123 // assume direct function calls.
124 return RM.value_or(u: Reloc::Static);
125}
126
127using WebAssembly::WasmDisableExplicitLocals;
128using WebAssembly::WasmEnableEmSjLj;
129using WebAssembly::WasmEnableSjLj;
130
131static void basicCheckForEHAndSjLj(TargetMachine *TM) {
132
133 bool EnableEmEH = TM->Options.ExceptionModel == ExceptionHandling::Emscripten;
134 bool EnableWasmEH = TM->Options.ExceptionModel == ExceptionHandling::Wasm;
135
136 // You can't enable two modes of SjLj at the same time
137 if (WasmEnableEmSjLj && WasmEnableSjLj)
138 report_fatal_error(
139 reason: "-enable-emscripten-sjlj not allowed with -wasm-enable-sjlj");
140 // You can't mix Emscripten EH with Wasm SjLj.
141 if (EnableEmEH && WasmEnableSjLj)
142 report_fatal_error(
143 reason: "-exception-model=emscripten not allowed with -wasm-enable-sjlj");
144 // You can't mix Wasm EH with Emscripten SjLj.
145 if (EnableWasmEH && WasmEnableEmSjLj)
146 report_fatal_error(
147 reason: "-exception-model=wasm not allowed with -enable-emscripten-sjlj");
148
149 if (TM->Options.ExceptionModel == ExceptionHandling::Default) {
150 // FIXME: This flag should be removed in favor of directly using the
151 // generically configured ExceptionsType.
152 if (WebAssembly::WasmEnableSjLj)
153 TM->Options.ExceptionModel = ExceptionHandling::Wasm;
154 }
155
156 // Basic Correctness checking related to -exception-model
157 if (TM->Options.ExceptionModel != ExceptionHandling::Default &&
158 TM->Options.ExceptionModel != ExceptionHandling::None &&
159 TM->Options.ExceptionModel != ExceptionHandling::Wasm &&
160 TM->Options.ExceptionModel != ExceptionHandling::Emscripten)
161 report_fatal_error(
162 reason: "-exception-model should be either 'none', 'wasm', or 'emscripten'");
163 if (WasmEnableSjLj && TM->Options.ExceptionModel != ExceptionHandling::Wasm)
164 report_fatal_error(
165 reason: "-wasm-enable-sjlj only allowed with -exception-model=wasm");
166}
167
168/// Create an WebAssembly architecture model.
169///
170WebAssemblyTargetMachine::WebAssemblyTargetMachine(
171 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
172 const TargetOptions &Options, std::optional<Reloc::Model> RM,
173 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
174 : CodeGenTargetMachineImpl(T, TT, CPU, FS, Options,
175 getEffectiveRelocModel(RM),
176 getEffectiveCodeModel(CM, Default: CodeModel::Large), OL),
177 TLOF(new WebAssemblyTargetObjectFile()) {
178 // WebAssembly type-checks instructions, but a noreturn function with a return
179 // type that doesn't match the context will cause a check failure. So we lower
180 // LLVM 'unreachable' to ISD::TRAP and then lower that to WebAssembly's
181 // 'unreachable' instructions which is meant for that case. Formerly, we also
182 // needed to add checks to SP failure emission in the instruction selection
183 // backends, but this has since been tied to TrapUnreachable and is no longer
184 // necessary.
185 this->Options.TrapUnreachable = true;
186 this->Options.NoTrapAfterNoreturn = false;
187
188 // WebAssembly treats each function as an independent unit. Force
189 // -ffunction-sections, effectively, so that we can emit them independently.
190 this->Options.FunctionSections = true;
191 this->Options.DataSections = true;
192 this->Options.UniqueSectionNames = true;
193
194 basicCheckForEHAndSjLj(TM: this);
195 initAsmInfo();
196
197 // WebAssembly does not run RegAllocFast; tied operands must be lowered by
198 // TwoAddressInstructionPass.
199 setEnableTiedFastRegAlloc(false);
200
201 LLT::setUseExtended(true);
202
203 // Note that we don't use setRequiresStructuredCFG(true). It disables
204 // optimizations than we're ok with, and want, such as critical edge
205 // splitting and tail merging.
206}
207
208WebAssemblyTargetMachine::~WebAssemblyTargetMachine() = default; // anchor.
209
210const WebAssemblySubtarget *
211WebAssemblyTargetMachine::getSubtargetImpl(StringRef CPU, StringRef FS,
212 StringRef ABIName) const {
213 auto &I = SubtargetMap[CPU.str() + FS.str() + ABIName.str()];
214 if (!I) {
215 I = std::make_unique<WebAssemblySubtarget>(args: TargetTriple, args&: CPU, args&: FS, args: *this,
216 args&: ABIName);
217 }
218 return I.get();
219}
220
221const WebAssemblySubtarget *
222WebAssemblyTargetMachine::getSubtargetImpl(const Function &F) const {
223 Attribute CPUAttr = F.getFnAttribute(Kind: "target-cpu");
224 Attribute FSAttr = F.getFnAttribute(Kind: "target-features");
225
226 StringRef CPU = CPUAttr.isValid() ? CPUAttr.getValueAsString() : TargetCPU;
227 StringRef FS = FSAttr.isValid() ? FSAttr.getValueAsString() : TargetFS;
228
229 return getSubtargetImpl(CPU, FS, ABIName: getTargetABIName(M: *F.getParent()));
230}
231
232namespace {
233
234/// WebAssembly Code Generator Pass Configuration Options.
235class WebAssemblyPassConfig final : public TargetPassConfig {
236public:
237 WebAssemblyPassConfig(WebAssemblyTargetMachine &TM, PassManagerBase &PM)
238 : TargetPassConfig(TM, PM) {}
239
240 WebAssemblyTargetMachine &getWebAssemblyTargetMachine() const {
241 return getTM<WebAssemblyTargetMachine>();
242 }
243
244 FunctionPass *createTargetRegisterAllocator(bool) override;
245
246 void addIRPasses() override;
247 void addPassesToHandleExceptions() override;
248 void addISelPrepare() override;
249 bool addInstSelector() override;
250 void addOptimizedRegAlloc() override;
251 void addPostRegAlloc() override;
252 bool addGCPasses() override { return false; }
253 void addPreEmitPass() override;
254 bool addPreISel() override;
255
256 // No reg alloc
257 bool addRegAssignAndRewriteFast() override { return false; }
258
259 // No reg alloc
260 bool addRegAssignAndRewriteOptimized() override { return false; }
261
262 bool addIRTranslator() override;
263 void addPreLegalizeMachineIR() override;
264 bool addLegalizeMachineIR() override;
265 void addPreRegBankSelect() override;
266 bool addRegBankSelect() override;
267 bool addGlobalInstructionSelect() override;
268};
269} // end anonymous namespace
270
271MachineFunctionInfo *WebAssemblyTargetMachine::createMachineFunctionInfo(
272 BumpPtrAllocator &Allocator, const Function &F,
273 const TargetSubtargetInfo *STI) const {
274 return WebAssemblyFunctionInfo::create<WebAssemblyFunctionInfo>(Allocator, F,
275 STI);
276}
277
278TargetTransformInfo
279WebAssemblyTargetMachine::getTargetTransformInfo(const Function &F) const {
280 return TargetTransformInfo(std::make_unique<WebAssemblyTTIImpl>(args: this, args: F));
281}
282
283TargetPassConfig *
284WebAssemblyTargetMachine::createPassConfig(PassManagerBase &PM) {
285 return new WebAssemblyPassConfig(*this, PM);
286}
287
288FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(bool) {
289 return nullptr; // No reg alloc
290}
291
292//===----------------------------------------------------------------------===//
293// The following functions are called from lib/CodeGen/Passes.cpp to modify
294// the CodeGen pass sequence.
295//===----------------------------------------------------------------------===//
296
297void WebAssemblyPassConfig::addIRPasses() {
298 // Add signatures to prototype-less function declarations
299 addPass(P: createWebAssemblyAddMissingPrototypesLegacyPass());
300
301 // Lower .llvm.global_dtors into .llvm.global_ctors with __cxa_atexit calls.
302 addPass(P: createLowerGlobalDtorsLegacyPass());
303
304 // Fix function bitcasts, as WebAssembly requires caller and callee signatures
305 // to match.
306 addPass(P: createWebAssemblyFixFunctionBitcastsLegacyPass());
307
308 // Optimize "returned" function attributes.
309 if (getOptLevel() != CodeGenOptLevel::None)
310 addPass(P: createWebAssemblyOptimizeReturnedLegacyPass());
311
312 // Wasm SjLj shares Emscripten SjLj's transformation, so it is handled here.
313 // Without Wasm or Emscripten EH, this also lowers invokes.
314 addPass(P: createWebAssemblyLowerEmscriptenEHSjLjLegacyPass());
315
316 // Expand indirectbr instructions to switches.
317 addPass(P: createIndirectBrExpandPass(OptLevel: getOptLevel()));
318
319 // Try to expand `vecreduce_{and, or}` into `{any, all}_true`.
320 addPass(P: createWebAssemblyReduceToAnyAllTrueLegacyPass(
321 TM&: getWebAssemblyTargetMachine()));
322
323 TargetPassConfig::addIRPasses();
324}
325
326void WebAssemblyPassConfig::addPassesToHandleExceptions() {
327 // Wasm EH needs WinEHPrepare to remove the catchswitch PHIs SelectionDAG
328 // cannot lower.
329 addPass(P: createWinEHPass());
330 addPass(P: createWasmEHPass());
331}
332
333void WebAssemblyPassConfig::addISelPrepare() {
334 // We need to move reference type allocas to WASM_ADDRESS_SPACE_VAR so that
335 // loads and stores are promoted to local.gets/local.sets.
336 addPass(P: createWebAssemblyRefTypeMem2LocalLegacyPass());
337 // Lower atomics and TLS if necessary
338 addPass(P: createWebAssemblyCoalesceFeaturesAndStripAtomicsLegacyPass(
339 TM&: getWebAssemblyTargetMachine()));
340
341 // This is a no-op if atomics are not used in the module
342 addPass(P: createAtomicExpandLegacyPass());
343
344 TargetPassConfig::addISelPrepare();
345}
346
347bool WebAssemblyPassConfig::addInstSelector() {
348 (void)TargetPassConfig::addInstSelector();
349 addPass(P: createWebAssemblyISelDagLegacyPass(TM&: getWebAssemblyTargetMachine(),
350 OptLevel: getOptLevel()));
351 // Run the argument-move pass immediately after the ScheduleDAG scheduler
352 // so that we can fix up the ARGUMENT instructions before anything else
353 // sees them in the wrong place.
354 addPass(P: createWebAssemblyArgumentMoveLegacyPass());
355 // Set the p2align operands. This information is present during ISel, however
356 // it's inconvenient to collect. Collect it now, and update the immediate
357 // operands.
358 addPass(P: createWebAssemblySetP2AlignOperandsLegacyPass());
359
360 // Eliminate range checks and add default targets to br_table instructions.
361 addPass(P: createWebAssemblyFixBrTableDefaultsLegacyPass());
362
363 // unreachable is terminator, non-terminator instruction after it is not
364 // allowed.
365 addPass(P: createWebAssemblyCleanCodeAfterTrapLegacyPass());
366
367 return false;
368}
369
370void WebAssemblyPassConfig::addOptimizedRegAlloc() {
371 // Currently RegisterCoalesce degrades wasm debug info quality by a
372 // significant margin. As a quick fix, disable this for -O1, which is often
373 // used for debugging large applications. Disabling this increases code size
374 // of Emscripten core benchmarks by ~5%, which is acceptable for -O1, which is
375 // usually not used for production builds.
376 // TODO Investigate why RegisterCoalesce degrades debug info quality and fix
377 // it properly
378 if (getOptLevel() == CodeGenOptLevel::Less)
379 disablePass(PassID: &RegisterCoalescerID);
380 TargetPassConfig::addOptimizedRegAlloc();
381}
382
383void WebAssemblyPassConfig::addPostRegAlloc() {
384 // TODO: The following CodeGen passes don't currently support code containing
385 // virtual registers. Consider removing their restrictions and re-enabling
386 // them.
387
388 // These functions all require the NoVRegs property.
389 disablePass(PassID: &MachineLateInstrsCleanupID);
390 disablePass(PassID: &MachineCopyPropagationID);
391 disablePass(PassID: &PostRAMachineSinkingID);
392 disablePass(PassID: &PostRASchedulerID);
393 disablePass(PassID: &FuncletLayoutID);
394 disablePass(PassID: &StackMapLivenessID);
395 disablePass(PassID: &PatchableFunctionID);
396 disablePass(PassID: &ShrinkWrapID);
397 disablePass(PassID: &RemoveLoadsIntoFakeUsesID);
398
399 // This pass hurts code size for wasm because it can generate irreducible
400 // control flow.
401 disablePass(PassID: &MachineBlockPlacementID);
402
403 TargetPassConfig::addPostRegAlloc();
404}
405
406void WebAssemblyPassConfig::addPreEmitPass() {
407 TargetPassConfig::addPreEmitPass();
408
409 // Nullify DBG_VALUE_LISTs that we cannot handle.
410 addPass(P: createWebAssemblyNullifyDebugValueListsLegacyPass());
411
412 // Remove any unreachable blocks that may be left floating around.
413 // Rare, but possible. Needed for WebAssemblyFixIrreducibleControlFlow.
414 addPass(PassID: &UnreachableMachineBlockElimID);
415
416 // Eliminate multiple-entry loops.
417 addPass(P: createWebAssemblyFixIrreducibleControlFlowLegacyPass());
418
419 // Do various transformations for exception handling.
420 // Every CFG-changing optimizations should come before this.
421 addPass(P: createWebAssemblyLateEHPrepareLegacyPass());
422
423 // Now that we have a prologue and epilogue and all frame indices are
424 // rewritten, eliminate SP and FP. This allows them to be stackified,
425 // colored, and numbered with the rest of the registers.
426 addPass(P: createWebAssemblyReplacePhysRegsLegacyPass());
427
428 // Preparations and optimizations related to register stackification.
429 if (getOptLevel() != CodeGenOptLevel::None) {
430 // Depend on LiveIntervals and perform some optimizations on it.
431 addPass(P: createWebAssemblyOptimizeLiveIntervalsLegacyPass());
432
433 // Prepare memory intrinsic calls for register stackifying.
434 addPass(P: createWebAssemblyMemIntrinsicResultsLegacyPass());
435 }
436
437 // Mark registers as representing wasm's value stack. This is a key
438 // code-compression technique in WebAssembly. We run this pass (and
439 // MemIntrinsicResults above) very late, so that it sees as much code as
440 // possible, including code emitted by PEI and expanded by late tail
441 // duplication.
442 addPass(P: createWebAssemblyRegStackifyLegacyPass(OptLevel: getOptLevel()));
443
444 if (getOptLevel() != CodeGenOptLevel::None) {
445 // Run the register coloring pass to reduce the total number of registers.
446 // This runs after stackification so that it doesn't consider registers
447 // that become stackified.
448 addPass(P: createWebAssemblyRegColoringLegacyPass());
449 }
450
451 // Sort the blocks of the CFG into topological order, a prerequisite for
452 // BLOCK and LOOP markers.
453 addPass(P: createWebAssemblyCFGSortLegacyPass());
454
455 // Insert BLOCK and LOOP markers.
456 addPass(P: createWebAssemblyCFGStackifyLegacyPass());
457
458 // Insert explicit local.get and local.set operators.
459 if (!WasmDisableExplicitLocals)
460 addPass(P: createWebAssemblyExplicitLocalsLegacyPass());
461
462 // Lower br_unless into br_if.
463 addPass(P: createWebAssemblyLowerBrUnlessLegacyPass());
464
465 // Perform the very last peephole optimizations on the code.
466 if (getOptLevel() != CodeGenOptLevel::None)
467 addPass(P: createWebAssemblyPeepholeLegacyPass());
468
469 // Create a mapping from LLVM CodeGen virtual registers to wasm registers.
470 addPass(P: createWebAssemblyRegNumberingLegacyPass());
471
472 // Fix debug_values whose defs have been stackified.
473 if (!WasmDisableExplicitLocals)
474 addPass(P: createWebAssemblyDebugFixupLegacyPass());
475
476 // Collect information to prepare for MC lowering / asm printing.
477 addPass(P: createWebAssemblyMCLowerPreLegacyPass());
478}
479
480bool WebAssemblyPassConfig::addPreISel() {
481 TargetPassConfig::addPreISel();
482 return false;
483}
484
485bool WebAssemblyPassConfig::addIRTranslator() {
486 addPass(P: new IRTranslatorLegacy());
487 return false;
488}
489
490void WebAssemblyPassConfig::addPreLegalizeMachineIR() {
491 if (getOptLevel() != CodeGenOptLevel::None) {
492 addPass(P: createWebAssemblyPreLegalizerCombinerLegacyPass());
493 }
494}
495bool WebAssemblyPassConfig::addLegalizeMachineIR() {
496 addPass(P: new LegalizerLegacy());
497 return false;
498}
499
500void WebAssemblyPassConfig::addPreRegBankSelect() {
501 if (getOptLevel() != CodeGenOptLevel::None) {
502 addPass(P: createWebAssemblyPostLegalizerCombinerLegacyPass());
503 }
504}
505
506bool WebAssemblyPassConfig::addRegBankSelect() {
507 addPass(P: new RegBankSelectLegacy());
508 return false;
509}
510
511bool WebAssemblyPassConfig::addGlobalInstructionSelect() {
512 addPass(P: new InstructionSelectLegacy(getOptLevel()));
513
514 // We insert only if ISelDAG won't insert these at a later point.
515 if (isGlobalISelAbortEnabled()) {
516 addPass(P: createWebAssemblyArgumentMoveLegacyPass());
517 addPass(P: createWebAssemblySetP2AlignOperandsLegacyPass());
518 addPass(P: createWebAssemblyFixBrTableDefaultsLegacyPass());
519 addPass(P: createWebAssemblyCleanCodeAfterTrapLegacyPass());
520 }
521
522 return false;
523}
524
525yaml::MachineFunctionInfo *
526WebAssemblyTargetMachine::createDefaultFuncInfoYAML() const {
527 return new yaml::WebAssemblyFunctionInfo();
528}
529
530yaml::MachineFunctionInfo *WebAssemblyTargetMachine::convertFuncInfoToYAML(
531 const MachineFunction &MF) const {
532 const auto *MFI = MF.getInfo<WebAssemblyFunctionInfo>();
533 return new yaml::WebAssemblyFunctionInfo(MF, *MFI);
534}
535
536bool WebAssemblyTargetMachine::parseMachineFunctionInfo(
537 const yaml::MachineFunctionInfo &MFI, PerFunctionMIParsingState &PFS,
538 SMDiagnostic &Error, SMRange &SourceRange) const {
539 const auto &YamlMFI = static_cast<const yaml::WebAssemblyFunctionInfo &>(MFI);
540 MachineFunction &MF = PFS.MF;
541 MF.getInfo<WebAssemblyFunctionInfo>()->initializeBaseYamlFields(MF, YamlMFI);
542 return false;
543}
544