LLVM 23.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"
28#include "llvm/CodeGen/Passes.h"
31#include "llvm/IR/Function.h"
39#include <optional>
40using namespace llvm;
41
42#define DEBUG_TYPE "wasm"
43
44// A command-line option to keep implicit locals
45// for the purpose of testing with lit/llc ONLY.
46// This produces output which is not valid WebAssembly, and is not supported
47// by assemblers/disassemblers and other MC based tools.
49 "wasm-disable-explicit-locals", cl::Hidden,
50 cl::desc("WebAssembly: output implicit locals in"
51 " instruction output for test purposes only."),
52 cl::init(false));
53
54// Exception handling & setjmp-longjmp handling related options.
55
56// Emscripten's asm.js-style exception handling
58 "enable-emscripten-cxx-exceptions",
59 cl::desc("WebAssembly Emscripten-style exception handling"),
60 cl::init(false));
61// Emscripten's asm.js-style setjmp/longjmp handling
63 "enable-emscripten-sjlj",
64 cl::desc("WebAssembly Emscripten-style setjmp/longjmp handling"),
65 cl::init(false));
66// Exception handling using wasm EH instructions
68 WebAssembly::WasmEnableEH("wasm-enable-eh",
69 cl::desc("WebAssembly exception handling"));
70// setjmp/longjmp handling using wasm EH instrutions
72 "wasm-enable-sjlj", cl::desc("WebAssembly setjmp/longjmp handling"));
73// If true, use the legacy Wasm EH proposal:
74// https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/legacy/Exceptions.md
75// And if false, use the standardized Wasm EH proposal:
76// https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md
77// Currently set to true by default because not all major web browsers turn on
78// the new standard proposal by default, but will later change to false.
80 "wasm-use-legacy-eh", cl::desc("WebAssembly exception handling (legacy)"),
81 cl::init(true));
82
85 // Register the target.
90
91 // Register backend passes
124}
125
126//===----------------------------------------------------------------------===//
127// WebAssembly Lowering public interface.
128//===----------------------------------------------------------------------===//
129
130static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) {
131 // Default to static relocation model. This should always be more optimial
132 // than PIC since the static linker can determine all global addresses and
133 // assume direct function calls.
134 return RM.value_or(Reloc::Static);
135}
136
141
143
144 // You can't enable two modes of EH at the same time
145 if (WasmEnableEmEH && WasmEnableEH)
147 "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-eh");
148 // You can't enable two modes of SjLj at the same time
149 if (WasmEnableEmSjLj && WasmEnableSjLj)
151 "-enable-emscripten-sjlj not allowed with -wasm-enable-sjlj");
152 // You can't mix Emscripten EH with Wasm SjLj.
153 if (WasmEnableEmEH && WasmEnableSjLj)
155 "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-sjlj");
156
158 // FIXME: These flags should be removed in favor of directly using the
159 // generically configured ExceptionsType
162 }
163
164 // Basic Correctness checking related to -exception-model
167 report_fatal_error("-exception-model should be either 'none' or 'wasm'");
168 if (WasmEnableEmEH && TM->Options.ExceptionModel == ExceptionHandling::Wasm)
169 report_fatal_error("-exception-model=wasm not allowed with "
170 "-enable-emscripten-cxx-exceptions");
171 if (WasmEnableEH && TM->Options.ExceptionModel != ExceptionHandling::Wasm)
173 "-wasm-enable-eh only allowed with -exception-model=wasm");
174 if (WasmEnableSjLj && TM->Options.ExceptionModel != ExceptionHandling::Wasm)
176 "-wasm-enable-sjlj only allowed with -exception-model=wasm");
177 if ((!WasmEnableEH && !WasmEnableSjLj) &&
180 "-exception-model=wasm only allowed with at least one of "
181 "-wasm-enable-eh or -wasm-enable-sjlj");
182
183 // Currently it is allowed to mix Wasm EH with Emscripten SjLj as an interim
184 // measure, but some code will error out at compile time in this combination.
185 // See WebAssemblyLowerEmscriptenEHSjLj pass for details.
186}
187
188/// Create an WebAssembly architecture model.
189///
191 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
192 const TargetOptions &Options, std::optional<Reloc::Model> RM,
193 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
194 : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options,
196 getEffectiveCodeModel(CM, CodeModel::Large), OL),
197 TLOF(new WebAssemblyTargetObjectFile()),
198 UsesMultivalueABI(Options.MCOptions.getABIName() == "experimental-mv") {
199 // WebAssembly type-checks instructions, but a noreturn function with a return
200 // type that doesn't match the context will cause a check failure. So we lower
201 // LLVM 'unreachable' to ISD::TRAP and then lower that to WebAssembly's
202 // 'unreachable' instructions which is meant for that case. Formerly, we also
203 // needed to add checks to SP failure emission in the instruction selection
204 // backends, but this has since been tied to TrapUnreachable and is no longer
205 // necessary.
206 this->Options.TrapUnreachable = true;
207 this->Options.NoTrapAfterNoreturn = false;
208
209 // WebAssembly treats each function as an independent unit. Force
210 // -ffunction-sections, effectively, so that we can emit them independently.
211 this->Options.FunctionSections = true;
212 this->Options.DataSections = true;
213 this->Options.UniqueSectionNames = true;
214
216 initAsmInfo();
217
219
220 // Note that we don't use setRequiresStructuredCFG(true). It disables
221 // optimizations than we're ok with, and want, such as critical edge
222 // splitting and tail merging.
223}
224
226
231
234 std::string FS) const {
235 auto &I = SubtargetMap[CPU + FS];
236 if (!I) {
237 I = std::make_unique<WebAssemblySubtarget>(TargetTriple, CPU, FS, *this);
238 }
239 return I.get();
240}
241
244 Attribute CPUAttr = F.getFnAttribute("target-cpu");
245 Attribute FSAttr = F.getFnAttribute("target-features");
246
247 std::string CPU =
248 CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
249 std::string FS =
250 FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
251
252 return getSubtargetImpl(CPU, FS);
253}
254
255namespace {
256
257class CoalesceFeaturesAndStripAtomics final : public ModulePass {
258 // Take the union of all features used in the module and use it for each
259 // function individually, since having multiple feature sets in one module
260 // currently does not make sense for WebAssembly. If atomics are not enabled,
261 // also strip atomic operations and thread local storage.
262 static char ID;
264
265public:
266 CoalesceFeaturesAndStripAtomics(WebAssemblyTargetMachine *WasmTM)
267 : ModulePass(ID), WasmTM(WasmTM) {}
268
269 bool runOnModule(Module &M) override {
270 auto [Features, FeatureStr] = coalesceFeatures(M);
271
272 WasmTM->setTargetFeatureString(FeatureStr);
273 for (auto &F : M)
274 replaceFeatures(F, FeatureStr);
275
276 bool StrippedAtomics = false;
277 bool StrippedTLS = false;
278
279 // In cooperative threading mode, thread locals are meaningful even without
280 // atomics.
281 const WebAssemblySubtarget *ST = WasmTM->getSubtargetImpl();
282 bool CooperativeThreading = ST->hasCooperativeMultithreading();
283
284 if (!Features[WebAssembly::FeatureAtomics]) {
285 StrippedAtomics = stripAtomics(M);
286 if (!CooperativeThreading)
287 StrippedTLS = stripThreadLocals(M);
288 }
289 if (!Features[WebAssembly::FeatureBulkMemory] && !StrippedTLS) {
290 StrippedTLS = stripThreadLocals(M);
291 }
292
293 if (StrippedAtomics && !StrippedTLS && !CooperativeThreading)
294 stripThreadLocals(M);
295 else if (StrippedTLS && !StrippedAtomics)
296 stripAtomics(M);
297
298 recordFeatures(M, ST, Features, StrippedAtomics || StrippedTLS);
299
300 // Conservatively assume we have made some change
301 return true;
302 }
303
304private:
305 std::pair<FeatureBitset, std::string> coalesceFeatures(const Module &M) {
306 // Union the features of all defined functions. Start with an empty set, so
307 // that if a feature is disabled in every function, we'll compute it as
308 // disabled. If any function lacks a target-features attribute, it'll
309 // default to the target CPU from the `TargetMachine`.
310 FeatureBitset Features;
311 // We need any MCSubtargetInfo to access WebAssemblyFeatureKV.
312 const WebAssemblySubtarget *AnyST = nullptr;
313 for (auto &F : M) {
314 if (F.isDeclaration())
315 continue;
316
317 AnyST = WasmTM->getSubtargetImpl(F);
318 Features |= AnyST->getFeatureBits();
319 }
320
321 // If we have no defined functions, use the target CPU from the
322 // `TargetMachine`.
323 if (!AnyST) {
324 AnyST = WasmTM->getSubtargetImpl(
325 std::string(WasmTM->getTargetCPU()),
326 std::string(WasmTM->getTargetFeatureString()));
327 Features = AnyST->getFeatureBits();
328 }
329
330 return {Features, getFeatureString(AnyST, Features)};
331 }
332
333 static std::string getFeatureString(const WebAssemblySubtarget *ST,
334 const FeatureBitset &Features) {
335 std::string Ret;
336 for (const SubtargetFeatureKV &KV : ST->getAllProcessorFeatures()) {
337 if (Features[KV.Value])
338 Ret += (StringRef("+") + KV.key() + ",").str();
339 else
340 Ret += (StringRef("-") + KV.key() + ",").str();
341 }
342 // remove trailing ','
343 Ret.pop_back();
344 return Ret;
345 }
346
347 void replaceFeatures(Function &F, const std::string &Features) {
348 F.removeFnAttr("target-features");
349 F.removeFnAttr("target-cpu");
350 F.addFnAttr("target-features", Features);
351 }
352
353 bool stripAtomics(Module &M) {
354 // Detect whether any atomics will be lowered, since there is no way to tell
355 // whether the LowerAtomic pass lowers e.g. stores.
356 bool Stripped = false;
357 for (auto &F : M) {
358 for (auto &B : F) {
359 for (auto &I : B) {
360 if (I.isAtomic()) {
361 Stripped = true;
362 goto done;
363 }
364 }
365 }
366 }
367
368 done:
369 if (!Stripped)
370 return false;
371
372 LowerAtomicPass Lowerer;
374 for (auto &F : M)
375 Lowerer.run(F, FAM);
376
377 return true;
378 }
379
380 bool stripThreadLocals(Module &M) {
381 bool Stripped = false;
382 for (auto &GV : M.globals()) {
383 if (GV.isThreadLocal()) {
384 // replace `@llvm.threadlocal.address.pX(GV)` with `GV`.
385 for (Use &U : make_early_inc_range(GV.uses())) {
386 if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(U.getUser())) {
387 if (II->getIntrinsicID() == Intrinsic::threadlocal_address &&
388 II->getArgOperand(0) == &GV) {
389 II->replaceAllUsesWith(&GV);
390 II->eraseFromParent();
391 }
392 }
393 }
394
395 Stripped = true;
396 GV.setThreadLocal(false);
397 }
398 }
399 return Stripped;
400 }
401
402 void recordFeatures(Module &M, const WebAssemblySubtarget *ST,
403 const FeatureBitset &Features, bool Stripped) {
404 for (const SubtargetFeatureKV &KV : ST->getAllProcessorFeatures()) {
405 if (Features[KV.Value]) {
406 // Mark features as used
407 std::string MDKey = (StringRef("wasm-feature-") + KV.key()).str();
408 M.addModuleFlag(Module::ModFlagBehavior::Error, MDKey,
410 }
411 }
412 // Code compiled without atomics or bulk-memory may have had its atomics or
413 // thread-local data lowered to nonatomic operations or non-thread-local
414 // data. In that case, we mark the pseudo-feature "shared-mem" as disallowed
415 // to tell the linker that it would be unsafe to allow this code to be used
416 // in a module with shared memory.
417 if (Stripped) {
418 M.addModuleFlag(Module::ModFlagBehavior::Error, "wasm-feature-shared-mem",
420 }
421 }
422};
423char CoalesceFeaturesAndStripAtomics::ID = 0;
424
425/// WebAssembly Code Generator Pass Configuration Options.
426class WebAssemblyPassConfig final : public TargetPassConfig {
427public:
428 WebAssemblyPassConfig(WebAssemblyTargetMachine &TM, PassManagerBase &PM)
429 : TargetPassConfig(TM, PM) {}
430
431 WebAssemblyTargetMachine &getWebAssemblyTargetMachine() const {
433 }
434
435 FunctionPass *createTargetRegisterAllocator(bool) override;
436
437 void addIRPasses() override;
438 void addISelPrepare() override;
439 bool addInstSelector() override;
440 void addOptimizedRegAlloc() override;
441 void addPostRegAlloc() override;
442 bool addGCPasses() override { return false; }
443 void addPreEmitPass() override;
444 bool addPreISel() override;
445
446 // No reg alloc
447 bool addRegAssignAndRewriteFast() override { return false; }
448
449 // No reg alloc
450 bool addRegAssignAndRewriteOptimized() override { return false; }
451
452 bool addIRTranslator() override;
453 void addPreLegalizeMachineIR() override;
454 bool addLegalizeMachineIR() override;
455 void addPreRegBankSelect() override;
456 bool addRegBankSelect() override;
457 bool addGlobalInstructionSelect() override;
458};
459} // end anonymous namespace
460
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
525 // Try to expand `vecreduce_{and, or}` into `{any, all}_true`.
526 addPass(createWebAssemblyReduceToAnyAllTrue(getWebAssemblyTargetMachine()));
527
529}
530
531void WebAssemblyPassConfig::addISelPrepare() {
532 // We need to move reference type allocas to WASM_ADDRESS_SPACE_VAR so that
533 // loads and stores are promoted to local.gets/local.sets.
535 // Lower atomics and TLS if necessary
536 addPass(new CoalesceFeaturesAndStripAtomics(&getWebAssemblyTargetMachine()));
537
538 // This is a no-op if atomics are not used in the module
540
542}
543
544bool WebAssemblyPassConfig::addInstSelector() {
546 addPass(
547 createWebAssemblyISelDag(getWebAssemblyTargetMachine(), getOptLevel()));
548 // Run the argument-move pass immediately after the ScheduleDAG scheduler
549 // so that we can fix up the ARGUMENT instructions before anything else
550 // sees them in the wrong place.
552 // Set the p2align operands. This information is present during ISel, however
553 // it's inconvenient to collect. Collect it now, and update the immediate
554 // operands.
556
557 // Eliminate range checks and add default targets to br_table instructions.
559
560 // unreachable is terminator, non-terminator instruction after it is not
561 // allowed.
563
564 return false;
565}
566
567void WebAssemblyPassConfig::addOptimizedRegAlloc() {
568 // Currently RegisterCoalesce degrades wasm debug info quality by a
569 // significant margin. As a quick fix, disable this for -O1, which is often
570 // used for debugging large applications. Disabling this increases code size
571 // of Emscripten core benchmarks by ~5%, which is acceptable for -O1, which is
572 // usually not used for production builds.
573 // TODO Investigate why RegisterCoalesce degrades debug info quality and fix
574 // it properly
575 if (getOptLevel() == CodeGenOptLevel::Less)
576 disablePass(&RegisterCoalescerID);
578}
579
580void WebAssemblyPassConfig::addPostRegAlloc() {
581 // TODO: The following CodeGen passes don't currently support code containing
582 // virtual registers. Consider removing their restrictions and re-enabling
583 // them.
584
585 // These functions all require the NoVRegs property.
586 disablePass(&MachineLateInstrsCleanupID);
587 disablePass(&MachineCopyPropagationID);
588 disablePass(&PostRAMachineSinkingID);
589 disablePass(&PostRASchedulerID);
590 disablePass(&FuncletLayoutID);
591 disablePass(&StackMapLivenessID);
592 disablePass(&PatchableFunctionID);
593 disablePass(&ShrinkWrapID);
594 disablePass(&RemoveLoadsIntoFakeUsesID);
595
596 // This pass hurts code size for wasm because it can generate irreducible
597 // control flow.
598 disablePass(&MachineBlockPlacementID);
599
601}
602
603void WebAssemblyPassConfig::addPreEmitPass() {
605
606 // Nullify DBG_VALUE_LISTs that we cannot handle.
608
609 // Remove any unreachable blocks that may be left floating around.
610 // Rare, but possible. Needed for WebAssemblyFixIrreducibleControlFlow.
612
613 // Eliminate multiple-entry loops.
615
616 // Do various transformations for exception handling.
617 // Every CFG-changing optimizations should come before this.
618 if (TM->Options.ExceptionModel == ExceptionHandling::Wasm)
620
621 // Now that we have a prologue and epilogue and all frame indices are
622 // rewritten, eliminate SP and FP. This allows them to be stackified,
623 // colored, and numbered with the rest of the registers.
625
626 // Preparations and optimizations related to register stackification.
627 if (getOptLevel() != CodeGenOptLevel::None) {
628 // Depend on LiveIntervals and perform some optimizations on it.
630
631 // Prepare memory intrinsic calls for register stackifying.
633 }
634
635 // Mark registers as representing wasm's value stack. This is a key
636 // code-compression technique in WebAssembly. We run this pass (and
637 // MemIntrinsicResults above) very late, so that it sees as much code as
638 // possible, including code emitted by PEI and expanded by late tail
639 // duplication.
640 addPass(createWebAssemblyRegStackify(getOptLevel()));
641
642 if (getOptLevel() != CodeGenOptLevel::None) {
643 // Run the register coloring pass to reduce the total number of registers.
644 // This runs after stackification so that it doesn't consider registers
645 // that become stackified.
647 }
648
649 // Sort the blocks of the CFG into topological order, a prerequisite for
650 // BLOCK and LOOP markers.
651 addPass(createWebAssemblyCFGSort());
652
653 // Insert BLOCK and LOOP markers.
655
656 // Insert explicit local.get and local.set operators.
659
660 // Lower br_unless into br_if.
662
663 // Perform the very last peephole optimizations on the code.
664 if (getOptLevel() != CodeGenOptLevel::None)
665 addPass(createWebAssemblyPeephole());
666
667 // Create a mapping from LLVM CodeGen virtual registers to wasm registers.
669
670 // Fix debug_values whose defs have been stackified.
673
674 // Collect information to prepare for MC lowering / asm printing.
676}
677
678bool WebAssemblyPassConfig::addPreISel() {
680 return false;
681}
682
683bool WebAssemblyPassConfig::addIRTranslator() {
684 addPass(new IRTranslator());
685 return false;
686}
687
688void WebAssemblyPassConfig::addPreLegalizeMachineIR() {
689 if (getOptLevel() != CodeGenOptLevel::None) {
691 }
692}
693bool WebAssemblyPassConfig::addLegalizeMachineIR() {
694 addPass(new Legalizer());
695 return false;
696}
697
698void WebAssemblyPassConfig::addPreRegBankSelect() {
699 if (getOptLevel() != CodeGenOptLevel::None) {
701 }
702}
703
704bool WebAssemblyPassConfig::addRegBankSelect() {
705 addPass(new RegBankSelect());
706 return false;
707}
708
709bool WebAssemblyPassConfig::addGlobalInstructionSelect() {
710 addPass(new InstructionSelect(getOptLevel()));
711
712 // We insert only if ISelDAG won't insert these at a later point.
713 if (isGlobalISelAbortEnabled()) {
718 }
719
720 return false;
721}
722
727
733
736 SMDiagnostic &Error, SMRange &SourceRange) const {
737 const auto &YamlMFI = static_cast<const yaml::WebAssemblyFunctionInfo &>(MFI);
738 MachineFunction &MF = PFS.MF;
739 MF.getInfo<WebAssemblyFunctionInfo>()->initializeBaseYamlFields(MF, YamlMFI);
740 return false;
741}
static Reloc::Model getEffectiveRelocModel()
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h:215
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
DXIL Legalizer
This file declares the IRTranslator pass.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
#define T
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
This file describes the interface of the MachineFunctionPass responsible for assigning the generic vi...
const GCNTargetMachine & getTM(const GCNSubtarget *STI)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
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 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))
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.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:105
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:261
CodeGenTargetMachineImpl(const Target &T, StringRef DataLayoutString, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOptLevel OL)
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
This pass is responsible for selecting generic machine instructions to target-specific instructions.
static void setUseExtended(bool Enable)
LLVM_ABI 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...
This pass implements the reg bank selector pass used in the GlobalISel pipeline.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition SourceMgr.h:303
Represents a range in source code.
Definition SMLoc.h:47
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
Primary interface to the complete machine description for the target machine.
Triple TargetTriple
Triple string, CPU name, and target feature strings the TargetMachine instance is created with.
StringRef getTargetFeatureString() const
StringRef getTargetCPU() const
std::unique_ptr< const MCSubtargetInfo > STI
TargetOptions Options
void setTargetFeatureString(StringRef FS)
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.
ExceptionHandling ExceptionModel
What exception model to use.
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
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)
@ WASM_FEATURE_PREFIX_USED
Definition Wasm.h:189
@ WASM_FEATURE_PREFIX_DISALLOWED
Definition Wasm.h:190
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI ModulePass * createLowerGlobalDtorsLegacyPass()
void initializeOptimizeReturnedPass(PassRegistry &)
LLVM_ABI FunctionPass * createIndirectBrExpandPass()
void initializeWebAssemblyLowerBrUnlessPass(PassRegistry &)
FunctionPass * createWebAssemblyRegNumbering()
ModulePass * createWebAssemblyAddMissingPrototypes()
LLVM_ABI char & RegisterCoalescerID
RegisterCoalescer - This pass merges live ranges to eliminate copies.
FunctionPass * createWebAssemblyLateEHPrepare()
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
void initializeWebAssemblyPostLegalizerCombinerPass(PassRegistry &)
void initializeWebAssemblyLateEHPreparePass(PassRegistry &)
@ None
No exception support.
Definition CodeGen.h:54
@ Wasm
WebAssembly Exception Handling.
Definition CodeGen.h:59
FunctionPass * createWebAssemblyFixBrTableDefaults()
void initializeWebAssemblyAddMissingPrototypesPass(PassRegistry &)
FunctionPass * createWebAssemblyReduceToAnyAllTrue(WebAssemblyTargetMachine &TM)
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:633
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 initializeWebAssemblyDAGToDAGISelLegacyPass(PassRegistry &)
FunctionPass * createWebAssemblyRegStackify(CodeGenOptLevel OptLevel)
FunctionPass * createWebAssemblyReplacePhysRegs()
void initializeWebAssemblyRegColoringPass(PassRegistry &)
static Reloc::Model getEffectiveRelocModel(std::optional< Reloc::Model > RM)
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.
LLVM_ABI char & MachineLateInstrsCleanupID
MachineLateInstrsCleanup - This pass removes redundant identical instructions after register allocati...
FunctionPass * createWebAssemblyDebugFixup()
LLVM_ABI char & UnreachableMachineBlockElimID
UnreachableMachineBlockElimination - This pass removes unreachable machine basic blocks.
LLVM_ABI FunctionPass * createLowerInvokePass()
Target & getTheWebAssemblyTarget32()
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
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 &)
LLVM_ABI void initializeGlobalISel(PassRegistry &)
Initialize all passes linked into the GlobalISel library.
void initializeWebAssemblyPreLegalizerCombinerPass(PassRegistry &)
FunctionPass * createWebAssemblyArgumentMove()
FunctionPass * createWebAssemblyExplicitLocals()
Target & getTheWebAssemblyTarget64()
void initializeWebAssemblyMemIntrinsicResultsPass(PassRegistry &)
void initializeWebAssemblyMCLowerPrePassPass(PassRegistry &)
void initializeWebAssemblyExplicitLocalsPass(PassRegistry &)
FunctionPass * createWebAssemblyPreLegalizerCombiner()
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.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI FunctionPass * createAtomicExpandLegacyPass()
AtomicExpandPass - At IR level this pass replace atomic instructions with __atomic_* library calls,...
FunctionPass * createWebAssemblyCFGSort()
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:390
void initializeWebAssemblyCFGSortPass(PassRegistry &)
void initializeWebAssemblyFixBrTableDefaultsPass(PassRegistry &)
FunctionPass * createWebAssemblyPostLegalizerCombiner()
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...
static FuncInfoTy * create(BumpPtrAllocator &Allocator, const Function &F, const SubtargetTy *STI)
Factory function: default behavior is to call new using the supplied allocator.
RegisterTargetMachine - Helper template for registering a target machine implementation,...
Targets should override this in a way that mirrors the implementation of llvm::MachineFunctionInfo.