LLVM 22.0.0git
WebAssemblyTargetMachine.cpp
Go to the documentation of this file.
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
17#include "WebAssembly.h"
24#include "llvm/CodeGen/Passes.h"
27#include "llvm/IR/Function.h"
35#include <optional>
36using namespace llvm;
37
38#define DEBUG_TYPE "wasm"
39
40// A command-line option to keep implicit locals
41// for the purpose of testing with lit/llc ONLY.
42// This produces output which is not valid WebAssembly, and is not supported
43// by assemblers/disassemblers and other MC based tools.
45 "wasm-disable-explicit-locals", cl::Hidden,
46 cl::desc("WebAssembly: output implicit locals in"
47 " instruction output for test purposes only."),
48 cl::init(false));
49
51 "wasm-disable-fix-irreducible-control-flow-pass", cl::Hidden,
52 cl::desc("webassembly: disables the fix "
53 " irreducible control flow optimization pass"),
54 cl::init(false));
55
56// Exception handling & setjmp-longjmp handling related options.
57
58// Emscripten's asm.js-style exception handling
60 "enable-emscripten-cxx-exceptions",
61 cl::desc("WebAssembly Emscripten-style exception handling"),
62 cl::init(false));
63// Emscripten's asm.js-style setjmp/longjmp handling
65 "enable-emscripten-sjlj",
66 cl::desc("WebAssembly Emscripten-style setjmp/longjmp handling"),
67 cl::init(false));
68// Exception handling using wasm EH instructions
70 WebAssembly::WasmEnableEH("wasm-enable-eh",
71 cl::desc("WebAssembly exception handling"));
72// setjmp/longjmp handling using wasm EH instrutions
74 "wasm-enable-sjlj", cl::desc("WebAssembly setjmp/longjmp handling"));
75// If true, use the legacy Wasm EH proposal:
76// https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/legacy/Exceptions.md
77// And if false, use the standardized Wasm EH proposal:
78// https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md
79// Currently set to true by default because not all major web browsers turn on
80// the new standard proposal by default, but will later change to false.
82 "wasm-use-legacy-eh", cl::desc("WebAssembly exception handling (legacy)"),
83 cl::init(true));
84
87 // Register the target.
92
93 // Register backend passes
124}
125
126//===----------------------------------------------------------------------===//
127// WebAssembly Lowering public interface.
128//===----------------------------------------------------------------------===//
129
130static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM,
131 const Triple &TT) {
132 if (!RM) {
133 // Default to static relocation model. This should always be more optimial
134 // than PIC since the static linker can determine all global addresses and
135 // assume direct function calls.
136 return Reloc::Static;
137 }
138
139 return *RM;
140}
141
146
148
149 // You can't enable two modes of EH at the same time
150 if (WasmEnableEmEH && WasmEnableEH)
152 "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-eh");
153 // You can't enable two modes of SjLj at the same time
154 if (WasmEnableEmSjLj && WasmEnableSjLj)
156 "-enable-emscripten-sjlj not allowed with -wasm-enable-sjlj");
157 // You can't mix Emscripten EH with Wasm SjLj.
158 if (WasmEnableEmEH && WasmEnableSjLj)
160 "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-sjlj");
161
162 if (TM->Options.ExceptionModel == ExceptionHandling::None) {
163 // FIXME: These flags should be removed in favor of directly using the
164 // generically configured ExceptionsType
166 TM->Options.ExceptionModel = ExceptionHandling::Wasm;
167 }
168
169 // Basic Correctness checking related to -exception-model
170 if (TM->Options.ExceptionModel != ExceptionHandling::None &&
171 TM->Options.ExceptionModel != ExceptionHandling::Wasm)
172 report_fatal_error("-exception-model should be either 'none' or 'wasm'");
173 if (WasmEnableEmEH && TM->Options.ExceptionModel == ExceptionHandling::Wasm)
174 report_fatal_error("-exception-model=wasm not allowed with "
175 "-enable-emscripten-cxx-exceptions");
176 if (WasmEnableEH && TM->Options.ExceptionModel != ExceptionHandling::Wasm)
178 "-wasm-enable-eh only allowed with -exception-model=wasm");
179 if (WasmEnableSjLj && TM->Options.ExceptionModel != ExceptionHandling::Wasm)
181 "-wasm-enable-sjlj only allowed with -exception-model=wasm");
182 if ((!WasmEnableEH && !WasmEnableSjLj) &&
183 TM->Options.ExceptionModel == ExceptionHandling::Wasm)
185 "-exception-model=wasm only allowed with at least one of "
186 "-wasm-enable-eh or -wasm-enable-sjlj");
187
188 // Currently it is allowed to mix Wasm EH with Emscripten SjLj as an interim
189 // measure, but some code will error out at compile time in this combination.
190 // See WebAssemblyLowerEmscriptenEHSjLj pass for details.
191}
192
193/// Create an WebAssembly architecture model.
194///
196 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
197 const TargetOptions &Options, std::optional<Reloc::Model> RM,
198 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
200 T,
201 TT.isArch64Bit()
202 ? (TT.isOSEmscripten() ? "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-"
203 "i128:128-f128:64-n32:64-S128-ni:1:10:20"
204 : "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-"
205 "i128:128-n32:64-S128-ni:1:10:20")
206 : (TT.isOSEmscripten() ? "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-"
207 "i128:128-f128:64-n32:64-S128-ni:1:10:20"
208 : "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-"
209 "i128:128-n32:64-S128-ni:1:10:20"),
210 TT, CPU, FS, Options, getEffectiveRelocModel(RM, TT),
211 getEffectiveCodeModel(CM, CodeModel::Large), OL),
212 TLOF(new WebAssemblyTargetObjectFile()),
213 UsesMultivalueABI(Options.MCOptions.getABIName() == "experimental-mv") {
214 // WebAssembly type-checks instructions, but a noreturn function with a return
215 // type that doesn't match the context will cause a check failure. So we lower
216 // LLVM 'unreachable' to ISD::TRAP and then lower that to WebAssembly's
217 // 'unreachable' instructions which is meant for that case. Formerly, we also
218 // needed to add checks to SP failure emission in the instruction selection
219 // backends, but this has since been tied to TrapUnreachable and is no longer
220 // necessary.
221 this->Options.TrapUnreachable = true;
222 this->Options.NoTrapAfterNoreturn = false;
223
224 // WebAssembly treats each function as an independent unit. Force
225 // -ffunction-sections, effectively, so that we can emit them independently.
226 this->Options.FunctionSections = true;
227 this->Options.DataSections = true;
228 this->Options.UniqueSectionNames = true;
229
230 initAsmInfo();
232 // Note that we don't use setRequiresStructuredCFG(true). It disables
233 // optimizations than we're ok with, and want, such as critical edge
234 // splitting and tail merging.
235}
236
238
240 return getSubtargetImpl(std::string(getTargetCPU()),
241 std::string(getTargetFeatureString()));
242}
243
246 std::string FS) const {
247 auto &I = SubtargetMap[CPU + FS];
248 if (!I) {
249 I = std::make_unique<WebAssemblySubtarget>(TargetTriple, CPU, FS, *this);
250 }
251 return I.get();
252}
253
256 Attribute CPUAttr = F.getFnAttribute("target-cpu");
257 Attribute FSAttr = F.getFnAttribute("target-features");
258
259 std::string CPU =
260 CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
261 std::string FS =
262 FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
263
264 // This needs to be done before we create a new subtarget since any
265 // creation will depend on the TM and the code generation flags on the
266 // function that reside in TargetOptions.
268
269 return getSubtargetImpl(CPU, FS);
270}
271
272namespace {
273
274class CoalesceFeaturesAndStripAtomics final : public ModulePass {
275 // Take the union of all features used in the module and use it for each
276 // function individually, since having multiple feature sets in one module
277 // currently does not make sense for WebAssembly. If atomics are not enabled,
278 // also strip atomic operations and thread local storage.
279 static char ID;
281
282public:
283 CoalesceFeaturesAndStripAtomics(WebAssemblyTargetMachine *WasmTM)
284 : ModulePass(ID), WasmTM(WasmTM) {}
285
286 bool runOnModule(Module &M) override {
287 FeatureBitset Features = coalesceFeatures(M);
288
289 std::string FeatureStr = getFeatureString(Features);
290 WasmTM->setTargetFeatureString(FeatureStr);
291 for (auto &F : M)
292 replaceFeatures(F, FeatureStr);
293
294 bool StrippedAtomics = false;
295 bool StrippedTLS = false;
296
297 if (!Features[WebAssembly::FeatureAtomics]) {
298 StrippedAtomics = stripAtomics(M);
299 StrippedTLS = stripThreadLocals(M);
300 } else if (!Features[WebAssembly::FeatureBulkMemory]) {
301 StrippedTLS |= stripThreadLocals(M);
302 }
303
304 if (StrippedAtomics && !StrippedTLS)
305 stripThreadLocals(M);
306 else if (StrippedTLS && !StrippedAtomics)
307 stripAtomics(M);
308
309 recordFeatures(M, Features, StrippedAtomics || StrippedTLS);
310
311 // Conservatively assume we have made some change
312 return true;
313 }
314
315private:
316 FeatureBitset coalesceFeatures(const Module &M) {
317 // Union the features of all defined functions. Start with an empty set, so
318 // that if a feature is disabled in every function, we'll compute it as
319 // disabled. If any function lacks a target-features attribute, it'll
320 // default to the target CPU from the `TargetMachine`.
321 FeatureBitset Features;
322 bool AnyDefinedFuncs = false;
323 for (auto &F : M) {
324 if (F.isDeclaration())
325 continue;
326
327 Features |= WasmTM->getSubtargetImpl(F)->getFeatureBits();
328 AnyDefinedFuncs = true;
329 }
330
331 // If we have no defined functions, use the target CPU from the
332 // `TargetMachine`.
333 if (!AnyDefinedFuncs) {
334 Features =
335 WasmTM
336 ->getSubtargetImpl(std::string(WasmTM->getTargetCPU()),
337 std::string(WasmTM->getTargetFeatureString()))
338 ->getFeatureBits();
339 }
340
341 return Features;
342 }
343
344 static std::string getFeatureString(const FeatureBitset &Features) {
345 std::string Ret;
346 for (const SubtargetFeatureKV &KV : WebAssemblyFeatureKV) {
347 if (Features[KV.Value])
348 Ret += (StringRef("+") + KV.Key + ",").str();
349 else
350 Ret += (StringRef("-") + KV.Key + ",").str();
351 }
352 return Ret;
353 }
354
355 void replaceFeatures(Function &F, const std::string &Features) {
356 F.removeFnAttr("target-features");
357 F.removeFnAttr("target-cpu");
358 F.addFnAttr("target-features", Features);
359 }
360
361 bool stripAtomics(Module &M) {
362 // Detect whether any atomics will be lowered, since there is no way to tell
363 // whether the LowerAtomic pass lowers e.g. stores.
364 bool Stripped = false;
365 for (auto &F : M) {
366 for (auto &B : F) {
367 for (auto &I : B) {
368 if (I.isAtomic()) {
369 Stripped = true;
370 goto done;
371 }
372 }
373 }
374 }
375
376 done:
377 if (!Stripped)
378 return false;
379
380 LowerAtomicPass Lowerer;
382 for (auto &F : M)
383 Lowerer.run(F, FAM);
384
385 return true;
386 }
387
388 bool stripThreadLocals(Module &M) {
389 bool Stripped = false;
390 for (auto &GV : M.globals()) {
391 if (GV.isThreadLocal()) {
392 // replace `@llvm.threadlocal.address.pX(GV)` with `GV`.
393 for (Use &U : make_early_inc_range(GV.uses())) {
394 if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(U.getUser())) {
395 if (II->getIntrinsicID() == Intrinsic::threadlocal_address &&
396 II->getArgOperand(0) == &GV) {
397 II->replaceAllUsesWith(&GV);
398 II->eraseFromParent();
399 }
400 }
401 }
402
403 Stripped = true;
404 GV.setThreadLocal(false);
405 }
406 }
407 return Stripped;
408 }
409
410 void recordFeatures(Module &M, const FeatureBitset &Features, bool Stripped) {
411 for (const SubtargetFeatureKV &KV : WebAssemblyFeatureKV) {
412 if (Features[KV.Value]) {
413 // Mark features as used
414 std::string MDKey = (StringRef("wasm-feature-") + KV.Key).str();
415 M.addModuleFlag(Module::ModFlagBehavior::Error, MDKey,
417 }
418 }
419 // Code compiled without atomics or bulk-memory may have had its atomics or
420 // thread-local data lowered to nonatomic operations or non-thread-local
421 // data. In that case, we mark the pseudo-feature "shared-mem" as disallowed
422 // to tell the linker that it would be unsafe to allow this code ot be used
423 // in a module with shared memory.
424 if (Stripped) {
425 M.addModuleFlag(Module::ModFlagBehavior::Error, "wasm-feature-shared-mem",
427 }
428 }
429};
430char CoalesceFeaturesAndStripAtomics::ID = 0;
431
432/// WebAssembly Code Generator Pass Configuration Options.
433class WebAssemblyPassConfig final : public TargetPassConfig {
434public:
435 WebAssemblyPassConfig(WebAssemblyTargetMachine &TM, PassManagerBase &PM)
436 : TargetPassConfig(TM, PM) {}
437
438 WebAssemblyTargetMachine &getWebAssemblyTargetMachine() const {
439 return getTM<WebAssemblyTargetMachine>();
440 }
441
442 FunctionPass *createTargetRegisterAllocator(bool) override;
443
444 void addIRPasses() override;
445 void addISelPrepare() override;
446 bool addInstSelector() override;
447 void addOptimizedRegAlloc() override;
448 void addPostRegAlloc() override;
449 bool addGCPasses() override { return false; }
450 void addPreEmitPass() override;
451 bool addPreISel() override;
452
453 // No reg alloc
454 bool addRegAssignAndRewriteFast() override { return false; }
455
456 // No reg alloc
457 bool addRegAssignAndRewriteOptimized() override { return false; }
458};
459} // end anonymous namespace
460
462 BumpPtrAllocator &Allocator, const Function &F,
463 const TargetSubtargetInfo *STI) const {
464 return WebAssemblyFunctionInfo::create<WebAssemblyFunctionInfo>(Allocator, F,
465 STI);
466}
467
470 return TargetTransformInfo(std::make_unique<WebAssemblyTTIImpl>(this, F));
471}
472
475 return new WebAssemblyPassConfig(*this, PM);
476}
477
478FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(bool) {
479 return nullptr; // No reg alloc
480}
481
482//===----------------------------------------------------------------------===//
483// The following functions are called from lib/CodeGen/Passes.cpp to modify
484// the CodeGen pass sequence.
485//===----------------------------------------------------------------------===//
486
487void WebAssemblyPassConfig::addIRPasses() {
488 // Add signatures to prototype-less function declarations
490
491 // Lower .llvm.global_dtors into .llvm.global_ctors with __cxa_atexit calls.
493
494 // Fix function bitcasts, as WebAssembly requires caller and callee signatures
495 // to match.
497
498 // Optimize "returned" function attributes.
499 if (getOptLevel() != CodeGenOptLevel::None)
501
502 // If exception handling is not enabled and setjmp/longjmp handling is
503 // enabled, we lower invokes into calls and delete unreachable landingpad
504 // blocks. Lowering invokes when there is no EH support is done in
505 // TargetPassConfig::addPassesToHandleExceptions, but that runs after these IR
506 // passes and Emscripten SjLj handling expects all invokes to be lowered
507 // before.
508 if (!WasmEnableEmEH && !WasmEnableEH) {
509 addPass(createLowerInvokePass());
510 // The lower invoke pass may create unreachable code. Remove it in order not
511 // to process dead blocks in setjmp/longjmp handling.
513 }
514
515 // Handle exceptions and setjmp/longjmp if enabled. Unlike Wasm EH preparation
516 // done in WasmEHPrepare pass, Wasm SjLj preparation shares libraries and
517 // transformation algorithms with Emscripten SjLj, so we run
518 // LowerEmscriptenEHSjLj pass also when Wasm SjLj is enabled.
519 if (WasmEnableEmEH || WasmEnableEmSjLj || WasmEnableSjLj)
521
522 // Expand indirectbr instructions to switches.
524
526}
527
528void WebAssemblyPassConfig::addISelPrepare() {
529 // We need to move reference type allocas to WASM_ADDRESS_SPACE_VAR so that
530 // loads and stores are promoted to local.gets/local.sets.
532 // Lower atomics and TLS if necessary
533 addPass(new CoalesceFeaturesAndStripAtomics(&getWebAssemblyTargetMachine()));
534
535 // This is a no-op if atomics are not used in the module
537
539}
540
541bool WebAssemblyPassConfig::addInstSelector() {
543 addPass(
544 createWebAssemblyISelDag(getWebAssemblyTargetMachine(), getOptLevel()));
545 // Run the argument-move pass immediately after the ScheduleDAG scheduler
546 // so that we can fix up the ARGUMENT instructions before anything else
547 // sees them in the wrong place.
549 // Set the p2align operands. This information is present during ISel, however
550 // it's inconvenient to collect. Collect it now, and update the immediate
551 // operands.
553
554 // Eliminate range checks and add default targets to br_table instructions.
556
557 // unreachable is terminator, non-terminator instruction after it is not
558 // allowed.
560
561 return false;
562}
563
564void WebAssemblyPassConfig::addOptimizedRegAlloc() {
565 // Currently RegisterCoalesce degrades wasm debug info quality by a
566 // significant margin. As a quick fix, disable this for -O1, which is often
567 // used for debugging large applications. Disabling this increases code size
568 // of Emscripten core benchmarks by ~5%, which is acceptable for -O1, which is
569 // usually not used for production builds.
570 // TODO Investigate why RegisterCoalesce degrades debug info quality and fix
571 // it properly
572 if (getOptLevel() == CodeGenOptLevel::Less)
573 disablePass(&RegisterCoalescerID);
575}
576
577void WebAssemblyPassConfig::addPostRegAlloc() {
578 // TODO: The following CodeGen passes don't currently support code containing
579 // virtual registers. Consider removing their restrictions and re-enabling
580 // them.
581
582 // These functions all require the NoVRegs property.
583 disablePass(&MachineLateInstrsCleanupID);
584 disablePass(&MachineCopyPropagationID);
585 disablePass(&PostRAMachineSinkingID);
586 disablePass(&PostRASchedulerID);
587 disablePass(&FuncletLayoutID);
588 disablePass(&StackMapLivenessID);
589 disablePass(&PatchableFunctionID);
590 disablePass(&ShrinkWrapID);
591 disablePass(&RemoveLoadsIntoFakeUsesID);
592
593 // This pass hurts code size for wasm because it can generate irreducible
594 // control flow.
595 disablePass(&MachineBlockPlacementID);
596
598}
599
600void WebAssemblyPassConfig::addPreEmitPass() {
602
603 // Nullify DBG_VALUE_LISTs that we cannot handle.
605
606 // Eliminate multiple-entry loops.
609
610 // Do various transformations for exception handling.
611 // Every CFG-changing optimizations should come before this.
612 if (TM->Options.ExceptionModel == ExceptionHandling::Wasm)
614
615 // Now that we have a prologue and epilogue and all frame indices are
616 // rewritten, eliminate SP and FP. This allows them to be stackified,
617 // colored, and numbered with the rest of the registers.
619
620 // Preparations and optimizations related to register stackification.
621 if (getOptLevel() != CodeGenOptLevel::None) {
622 // Depend on LiveIntervals and perform some optimizations on it.
624
625 // Prepare memory intrinsic calls for register stackifying.
627 }
628
629 // Mark registers as representing wasm's value stack. This is a key
630 // code-compression technique in WebAssembly. We run this pass (and
631 // MemIntrinsicResults above) very late, so that it sees as much code as
632 // possible, including code emitted by PEI and expanded by late tail
633 // duplication.
634 addPass(createWebAssemblyRegStackify(getOptLevel()));
635
636 if (getOptLevel() != CodeGenOptLevel::None) {
637 // Run the register coloring pass to reduce the total number of registers.
638 // This runs after stackification so that it doesn't consider registers
639 // that become stackified.
641 }
642
643 // Sort the blocks of the CFG into topological order, a prerequisite for
644 // BLOCK and LOOP markers.
645 addPass(createWebAssemblyCFGSort());
646
647 // Insert BLOCK and LOOP markers.
649
650 // Insert explicit local.get and local.set operators.
653
654 // Lower br_unless into br_if.
656
657 // Perform the very last peephole optimizations on the code.
658 if (getOptLevel() != CodeGenOptLevel::None)
659 addPass(createWebAssemblyPeephole());
660
661 // Create a mapping from LLVM CodeGen virtual registers to wasm registers.
663
664 // Fix debug_values whose defs have been stackified.
667
668 // Collect information to prepare for MC lowering / asm printing.
670}
671
672bool WebAssemblyPassConfig::addPreISel() {
675 return false;
676}
677
681}
682
684 const MachineFunction &MF) const {
685 const auto *MFI = MF.getInfo<WebAssemblyFunctionInfo>();
686 return new yaml::WebAssemblyFunctionInfo(MF, *MFI);
687}
688
691 SMDiagnostic &Error, SMRange &SourceRange) const {
692 const auto &YamlMFI = static_cast<const yaml::WebAssemblyFunctionInfo &>(MFI);
693 MachineFunction &MF = PFS.MF;
694 MF.getInfo<WebAssemblyFunctionInfo>()->initializeBaseYamlFields(MF, YamlMFI);
695 return false;
696}
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition: Compiler.h:213
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:132
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static LVOptions Options
Definition: LVOptions.cpp:25
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
FunctionAnalysisManager FAM
Basic Register Allocator
Target-Independent Code Generator Pass Configuration Options pass.
This file defines the interfaces that WebAssembly uses to lower LLVM code into a selection DAG.
This file provides WebAssembly-specific target descriptions.
This file declares WebAssembly-specific per-machine-function information.
This file registers the WebAssembly target.
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyTarget()
static Reloc::Model getEffectiveRelocModel(std::optional< Reloc::Model > RM, const Triple &TT)
static void basicCheckForEHAndSjLj(TargetMachine *TM)
static cl::opt< bool > WasmDisableExplicitLocals("wasm-disable-explicit-locals", cl::Hidden, cl::desc("WebAssembly: output implicit locals in" " instruction output for test purposes only."), cl::init(false))
static cl::opt< bool > WasmDisableFixIrreducibleControlFlowPass("wasm-disable-fix-irreducible-control-flow-pass", cl::Hidden, cl::desc("webassembly: disables the fix " " irreducible control flow optimization pass"), cl::init(false))
This file declares the WebAssembly-specific subclass of TargetMachine.
This file declares the WebAssembly-specific subclass of TargetLoweringObjectFile.
This file a TargetTransformInfoImplBase conforming object specific to the WebAssembly target machine.
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.
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:255
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
Definition: Attributes.cpp:400
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition: Attributes.h:223
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:67
implements a set of functionality in the TargetMachine class for targets that make use of the indepen...
Lightweight error class with error context and mandatory checking.
Definition: Error.h:159
Container class for subtarget features.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:314
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:49
A pass that lowers atomic intrinsic into non-atomic intrinsics.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &)
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:255
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition: SourceMgr.h:282
Represents a range in source code.
Definition: SMLoc.h:48
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:233
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:83
Triple TargetTriple
Triple string, CPU name, and target feature strings the TargetMachine instance is created with.
std::string TargetFS
StringRef getTargetFeatureString() const
StringRef getTargetCPU() const
std::string TargetCPU
std::unique_ptr< const MCSubtargetInfo > STI
void setTargetFeatureString(StringRef FS)
void resetTargetOptions(const Function &F) const
Reset the target options based on the function's attributes.
unsigned UniqueSectionNames
unsigned FunctionSections
Emit functions into separate sections.
unsigned NoTrapAfterNoreturn
Do not emit a trap instruction for 'unreachable' IR instructions behind noreturn calls,...
unsigned DataSections
Emit data into separate sections.
unsigned TrapUnreachable
Emit target-specific trap instruction for 'unreachable' IR instructions.
Target-Independent Code Generator Pass Configuration Options.
virtual void addPostRegAlloc()
This method may be implemented by targets that want to run passes after register allocation pass pipe...
virtual bool addInstSelector()
addInstSelector - This method should install an instruction selector pass, which converts from LLVM c...
virtual bool addPreISel()
Methods with trivial inline returns are convenient points in the common codegen pass pipeline where t...
virtual void addOptimizedRegAlloc()
addOptimizedRegAlloc - Add passes related to register allocation.
virtual void addPreEmitPass()
This pass may be implemented by targets that want to run passes immediately before machine code is em...
virtual void addIRPasses()
Add common target configurable passes that perform LLVM IR to IR transforms following machine indepen...
virtual void addISelPrepare()
Add common passes that perform LLVM IR to IR transforms in preparation for instruction selection.
TargetSubtargetInfo - Generic base class for all target subtargets.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:47
A Use represents the edge between a Value definition and its users.
Definition: Use.h:35
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
yaml::MachineFunctionInfo * createDefaultFuncInfoYAML() const override
Allocate and return a default initialized instance of the YAML representation for the MachineFunction...
bool parseMachineFunctionInfo(const yaml::MachineFunctionInfo &, PerFunctionMIParsingState &PFS, SMDiagnostic &Error, SMRange &SourceRange) const override
Parse out the target's MachineFunctionInfo from the YAML reprsentation.
WebAssemblyTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM, CodeGenOptLevel OL, bool JIT)
Create an WebAssembly architecture model.
TargetPassConfig * createPassConfig(PassManagerBase &PM) override
Create a pass configuration object to be used by addPassToEmitX methods for generating a pipeline of ...
const WebAssemblySubtarget * getSubtargetImpl() const
MachineFunctionInfo * createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F, const TargetSubtargetInfo *STI) const override
Create the target's instance of MachineFunctionInfo.
TargetTransformInfo getTargetTransformInfo(const Function &F) const override
Get a TargetTransformInfo implementation for the target.
yaml::MachineFunctionInfo * convertFuncInfoToYAML(const MachineFunction &MF) const override
Allocate and initialize an instance of the YAML representation of the MachineFunctionInfo.
PassManagerBase - An abstract interface to allow code to add passes to a pass manager without having ...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
cl::opt< bool > WasmUseLegacyEH
cl::opt< bool > WasmEnableEH
cl::opt< bool > WasmEnableSjLj
cl::opt< bool > WasmEnableEmEH
cl::opt< bool > WasmEnableEmSjLj
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:444
@ WASM_FEATURE_PREFIX_USED
Definition: Wasm.h:180
@ WASM_FEATURE_PREFIX_DISALLOWED
Definition: Wasm.h:181
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
LLVM_ABI ModulePass * createLowerGlobalDtorsLegacyPass()
void initializeOptimizeReturnedPass(PassRegistry &)
LLVM_ABI FunctionPass * createIndirectBrExpandPass()
void initializeWebAssemblyLowerBrUnlessPass(PassRegistry &)
FunctionPass * createWebAssemblyLowerRefTypesIntPtrConv()
FunctionPass * createWebAssemblyRegNumbering()
ModulePass * createWebAssemblyAddMissingPrototypes()
LLVM_ABI char & RegisterCoalescerID
RegisterCoalescer - This pass merges live ranges to eliminate copies.
FunctionPass * createWebAssemblyLateEHPrepare()
const SubtargetFeatureKV WebAssemblyFeatureKV[WebAssembly::NumSubtargetFeatures]
void initializeWebAssemblyLateEHPreparePass(PassRegistry &)
@ Wasm
WebAssembly Exception Handling.
FunctionPass * createWebAssemblyFixBrTableDefaults()
void initializeWebAssemblyAddMissingPrototypesPass(PassRegistry &)
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:663
LLVM_ABI char & PatchableFunctionID
This pass implements the "patchable-function" attribute.
void initializeWebAssemblyExceptionInfoPass(PassRegistry &)
LLVM_ABI char & PostRASchedulerID
PostRAScheduler - This pass performs post register allocation scheduling.
LLVM_ABI char & RemoveLoadsIntoFakeUsesID
RemoveLoadsIntoFakeUses pass.
void initializeWebAssemblyRegNumberingPass(PassRegistry &)
void initializeWebAssemblyLowerRefTypesIntPtrConvPass(PassRegistry &)
void initializeWebAssemblyDAGToDAGISelLegacyPass(PassRegistry &)
FunctionPass * createWebAssemblyRegStackify(CodeGenOptLevel OptLevel)
FunctionPass * createWebAssemblyReplacePhysRegs()
void initializeWebAssemblyRegColoringPass(PassRegistry &)
CodeModel::Model getEffectiveCodeModel(std::optional< CodeModel::Model > CM, CodeModel::Model Default)
Helper method for getting the code model, returning Default if CM does not have a value.
FunctionPass * createWebAssemblyMemIntrinsicResults()
LLVM_ABI char & ShrinkWrapID
ShrinkWrap pass. Look for the best place to insert save and restore.
Definition: ShrinkWrap.cpp:292
LLVM_ABI char & MachineLateInstrsCleanupID
MachineLateInstrsCleanup - This pass removes redundant identical instructions after register allocati...
FunctionPass * createWebAssemblyDebugFixup()
LLVM_ABI FunctionPass * createLowerInvokePass()
Definition: LowerInvoke.cpp:85
Target & getTheWebAssemblyTarget32()
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition: Error.cpp:167
void initializeWebAssemblyNullifyDebugValueListsPass(PassRegistry &)
LLVM_ABI char & StackMapLivenessID
StackMapLiveness - This pass analyses the register live-out set of stackmap/patchpoint intrinsics and...
LLVM_ABI void initializeLowerGlobalDtorsLegacyPassPass(PassRegistry &)
void initializeWebAssemblyFixIrreducibleControlFlowPass(PassRegistry &)
FunctionPass * createWebAssemblyISelDag(WebAssemblyTargetMachine &TM, CodeGenOptLevel OptLevel)
This pass converts a legalized DAG into a WebAssembly-specific DAG, ready for instruction scheduling.
LLVM_ABI char & FuncletLayoutID
This pass lays out funclets contiguously.
void initializeWebAssemblyRegStackifyPass(PassRegistry &)
FunctionPass * createWebAssemblyCFGStackify()
FunctionPass * createWebAssemblyOptimizeLiveIntervals()
LLVM_ABI char & PostRAMachineSinkingID
This pass perform post-ra machine sink for COPY instructions.
CodeGenOptLevel
Code generation optimization level.
Definition: CodeGen.h:82
FunctionPass * createWebAssemblyOptimizeReturned()
FunctionPass * createWebAssemblyRefTypeMem2Local()
FunctionPass * createWebAssemblyCleanCodeAfterTrap()
void initializeWebAssemblyOptimizeLiveIntervalsPass(PassRegistry &)
FunctionPass * createWebAssemblySetP2AlignOperands()
ModulePass * createWebAssemblyLowerEmscriptenEHSjLj()
void initializeWebAssemblyLowerEmscriptenEHSjLjPass(PassRegistry &)
FunctionPass * createWebAssemblyArgumentMove()
FunctionPass * createWebAssemblyExplicitLocals()
Target & getTheWebAssemblyTarget64()
void initializeWebAssemblyMemIntrinsicResultsPass(PassRegistry &)
void initializeWebAssemblyMCLowerPrePassPass(PassRegistry &)
void initializeWebAssemblyExplicitLocalsPass(PassRegistry &)
FunctionPass * createWebAssemblyFixIrreducibleControlFlow()
ModulePass * createWebAssemblyFixFunctionBitcasts()
FunctionPass * createWebAssemblyLowerBrUnless()
void initializeFixFunctionBitcastsPass(PassRegistry &)
FunctionPass * createWebAssemblyRegColoring()
void initializeWebAssemblyPeepholePass(PassRegistry &)
ModulePass * createWebAssemblyMCLowerPrePass()
void initializeWebAssemblyRefTypeMem2LocalPass(PassRegistry &)
LLVM_ABI char & MachineBlockPlacementID
MachineBlockPlacement - This pass places basic blocks based on branch probabilities.
LLVM_ABI FunctionPass * createAtomicExpandLegacyPass()
AtomicExpandPass - At IR level this pass replace atomic instructions with __atomic_* library calls,...
FunctionPass * createWebAssemblyCFGSort()
void initializeWebAssemblyCFGSortPass(PassRegistry &)
void initializeWebAssemblyFixBrTableDefaultsPass(PassRegistry &)
FunctionPass * createWebAssemblyNullifyDebugValueLists()
void initializeWebAssemblyAsmPrinterPass(PassRegistry &)
void initializeWebAssemblyCFGStackifyPass(PassRegistry &)
void initializeWebAssemblySetP2AlignOperandsPass(PassRegistry &)
void initializeWebAssemblyDebugFixupPass(PassRegistry &)
LLVM_ABI char & MachineCopyPropagationID
MachineCopyPropagation - This pass performs copy propagation on machine instructions.
void initializeWebAssemblyArgumentMovePass(PassRegistry &)
LLVM_ABI FunctionPass * createUnreachableBlockEliminationPass()
createUnreachableBlockEliminationPass - The LLVM code generator does not work well with unreachable b...
FunctionPass * createWebAssemblyPeephole()
void initializeWebAssemblyReplacePhysRegsPass(PassRegistry &)
MachineFunctionInfo - This class can be derived from and used by targets to hold private target-speci...
RegisterTargetMachine - Helper template for registering a target machine implementation,...
Used to provide key value pairs for feature and CPU bit flags.
Targets should override this in a way that mirrors the implementation of llvm::MachineFunctionInfo.