LLVM 20.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"
25#include "llvm/CodeGen/Passes.h"
28#include "llvm/IR/Function.h"
30#include "llvm/MC/MCAsmInfo.h"
36#include <optional>
37using namespace llvm;
38
39#define DEBUG_TYPE "wasm"
40
41// A command-line option to keep implicit locals
42// for the purpose of testing with lit/llc ONLY.
43// This produces output which is not valid WebAssembly, and is not supported
44// by assemblers/disassemblers and other MC based tools.
46 "wasm-disable-explicit-locals", cl::Hidden,
47 cl::desc("WebAssembly: output implicit locals in"
48 " instruction output for test purposes only."),
49 cl::init(false));
50
52 "wasm-disable-fix-irreducible-control-flow-pass", cl::Hidden,
53 cl::desc("webassembly: disables the fix "
54 " irreducible control flow optimization pass"),
55 cl::init(false));
56
58 // Register the target.
63
64 // Register backend passes
94}
95
96//===----------------------------------------------------------------------===//
97// WebAssembly Lowering public interface.
98//===----------------------------------------------------------------------===//
99
100static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM,
101 const Triple &TT) {
102 if (!RM) {
103 // Default to static relocation model. This should always be more optimial
104 // than PIC since the static linker can determine all global addresses and
105 // assume direct function calls.
106 return Reloc::Static;
107 }
108
109 return *RM;
110}
111
112/// Create an WebAssembly architecture model.
113///
115 const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
116 const TargetOptions &Options, std::optional<Reloc::Model> RM,
117 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT)
119 T,
120 TT.isArch64Bit()
121 ? (TT.isOSEmscripten() ? "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-"
122 "f128:64-n32:64-S128-ni:1:10:20"
123 : "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-"
124 "n32:64-S128-ni:1:10:20")
125 : (TT.isOSEmscripten() ? "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-"
126 "f128:64-n32:64-S128-ni:1:10:20"
127 : "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-"
128 "n32:64-S128-ni:1:10:20"),
129 TT, CPU, FS, Options, getEffectiveRelocModel(RM, TT),
130 getEffectiveCodeModel(CM, CodeModel::Large), OL),
131 TLOF(new WebAssemblyTargetObjectFile()),
132 UsesMultivalueABI(Options.MCOptions.getABIName() == "experimental-mv") {
133 // WebAssembly type-checks instructions, but a noreturn function with a return
134 // type that doesn't match the context will cause a check failure. So we lower
135 // LLVM 'unreachable' to ISD::TRAP and then lower that to WebAssembly's
136 // 'unreachable' instructions which is meant for that case.
137 this->Options.TrapUnreachable = true;
138 this->Options.NoTrapAfterNoreturn = false;
139
140 // WebAssembly treats each function as an independent unit. Force
141 // -ffunction-sections, effectively, so that we can emit them independently.
142 this->Options.FunctionSections = true;
143 this->Options.DataSections = true;
144 this->Options.UniqueSectionNames = true;
145
146 initAsmInfo();
147
148 // Note that we don't use setRequiresStructuredCFG(true). It disables
149 // optimizations than we're ok with, and want, such as critical edge
150 // splitting and tail merging.
151}
152
154
156 return getSubtargetImpl(std::string(getTargetCPU()),
157 std::string(getTargetFeatureString()));
158}
159
162 std::string FS) const {
163 auto &I = SubtargetMap[CPU + FS];
164 if (!I) {
165 I = std::make_unique<WebAssemblySubtarget>(TargetTriple, CPU, FS, *this);
166 }
167 return I.get();
168}
169
172 Attribute CPUAttr = F.getFnAttribute("target-cpu");
173 Attribute FSAttr = F.getFnAttribute("target-features");
174
175 std::string CPU =
176 CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
177 std::string FS =
178 FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
179
180 // This needs to be done before we create a new subtarget since any
181 // creation will depend on the TM and the code generation flags on the
182 // function that reside in TargetOptions.
184
185 return getSubtargetImpl(CPU, FS);
186}
187
188namespace {
189
190class CoalesceFeaturesAndStripAtomics final : public ModulePass {
191 // Take the union of all features used in the module and use it for each
192 // function individually, since having multiple feature sets in one module
193 // currently does not make sense for WebAssembly. If atomics are not enabled,
194 // also strip atomic operations and thread local storage.
195 static char ID;
197
198public:
199 CoalesceFeaturesAndStripAtomics(WebAssemblyTargetMachine *WasmTM)
200 : ModulePass(ID), WasmTM(WasmTM) {}
201
202 bool runOnModule(Module &M) override {
203 FeatureBitset Features = coalesceFeatures(M);
204
205 std::string FeatureStr =
206 getFeatureString(Features, WasmTM->getTargetFeatureString());
207 WasmTM->setTargetFeatureString(FeatureStr);
208 for (auto &F : M)
209 replaceFeatures(F, FeatureStr);
210
211 bool StrippedAtomics = false;
212 bool StrippedTLS = false;
213
214 if (!Features[WebAssembly::FeatureAtomics]) {
215 StrippedAtomics = stripAtomics(M);
216 StrippedTLS = stripThreadLocals(M);
217 } else if (!Features[WebAssembly::FeatureBulkMemory]) {
218 StrippedTLS |= stripThreadLocals(M);
219 }
220
221 if (StrippedAtomics && !StrippedTLS)
222 stripThreadLocals(M);
223 else if (StrippedTLS && !StrippedAtomics)
224 stripAtomics(M);
225
226 recordFeatures(M, Features, StrippedAtomics || StrippedTLS);
227
228 // Conservatively assume we have made some change
229 return true;
230 }
231
232private:
233 FeatureBitset coalesceFeatures(const Module &M) {
234 FeatureBitset Features =
235 WasmTM
236 ->getSubtargetImpl(std::string(WasmTM->getTargetCPU()),
237 std::string(WasmTM->getTargetFeatureString()))
238 ->getFeatureBits();
239 for (auto &F : M)
240 Features |= WasmTM->getSubtargetImpl(F)->getFeatureBits();
241 return Features;
242 }
243
244 static std::string getFeatureString(const FeatureBitset &Features,
245 StringRef TargetFS) {
246 std::string Ret;
247 for (const SubtargetFeatureKV &KV : WebAssemblyFeatureKV) {
248 if (Features[KV.Value])
249 Ret += (StringRef("+") + KV.Key + ",").str();
250 }
251 SubtargetFeatures TF{TargetFS};
252 for (std::string const &F : TF.getFeatures())
254 Ret += F + ",";
255 return Ret;
256 }
257
258 void replaceFeatures(Function &F, const std::string &Features) {
259 F.removeFnAttr("target-features");
260 F.removeFnAttr("target-cpu");
261 F.addFnAttr("target-features", Features);
262 }
263
264 bool stripAtomics(Module &M) {
265 // Detect whether any atomics will be lowered, since there is no way to tell
266 // whether the LowerAtomic pass lowers e.g. stores.
267 bool Stripped = false;
268 for (auto &F : M) {
269 for (auto &B : F) {
270 for (auto &I : B) {
271 if (I.isAtomic()) {
272 Stripped = true;
273 goto done;
274 }
275 }
276 }
277 }
278
279 done:
280 if (!Stripped)
281 return false;
282
283 LowerAtomicPass Lowerer;
285 for (auto &F : M)
286 Lowerer.run(F, FAM);
287
288 return true;
289 }
290
291 bool stripThreadLocals(Module &M) {
292 bool Stripped = false;
293 for (auto &GV : M.globals()) {
294 if (GV.isThreadLocal()) {
295 // replace `@llvm.threadlocal.address.pX(GV)` with `GV`.
296 for (Use &U : make_early_inc_range(GV.uses())) {
297 if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(U.getUser())) {
298 if (II->getIntrinsicID() == Intrinsic::threadlocal_address &&
299 II->getArgOperand(0) == &GV) {
300 II->replaceAllUsesWith(&GV);
301 II->eraseFromParent();
302 }
303 }
304 }
305
306 Stripped = true;
307 GV.setThreadLocal(false);
308 }
309 }
310 return Stripped;
311 }
312
313 void recordFeatures(Module &M, const FeatureBitset &Features, bool Stripped) {
314 for (const SubtargetFeatureKV &KV : WebAssemblyFeatureKV) {
315 if (Features[KV.Value]) {
316 // Mark features as used
317 std::string MDKey = (StringRef("wasm-feature-") + KV.Key).str();
318 M.addModuleFlag(Module::ModFlagBehavior::Error, MDKey,
320 }
321 }
322 // Code compiled without atomics or bulk-memory may have had its atomics or
323 // thread-local data lowered to nonatomic operations or non-thread-local
324 // data. In that case, we mark the pseudo-feature "shared-mem" as disallowed
325 // to tell the linker that it would be unsafe to allow this code ot be used
326 // in a module with shared memory.
327 if (Stripped) {
328 M.addModuleFlag(Module::ModFlagBehavior::Error, "wasm-feature-shared-mem",
330 }
331 }
332};
333char CoalesceFeaturesAndStripAtomics::ID = 0;
334
335/// WebAssembly Code Generator Pass Configuration Options.
336class WebAssemblyPassConfig final : public TargetPassConfig {
337public:
338 WebAssemblyPassConfig(WebAssemblyTargetMachine &TM, PassManagerBase &PM)
339 : TargetPassConfig(TM, PM) {}
340
341 WebAssemblyTargetMachine &getWebAssemblyTargetMachine() const {
342 return getTM<WebAssemblyTargetMachine>();
343 }
344
345 FunctionPass *createTargetRegisterAllocator(bool) override;
346
347 void addIRPasses() override;
348 void addISelPrepare() override;
349 bool addInstSelector() override;
350 void addOptimizedRegAlloc() override;
351 void addPostRegAlloc() override;
352 bool addGCPasses() override { return false; }
353 void addPreEmitPass() override;
354 bool addPreISel() override;
355
356 // No reg alloc
357 bool addRegAssignAndRewriteFast() override { return false; }
358
359 // No reg alloc
360 bool addRegAssignAndRewriteOptimized() override { return false; }
361};
362} // end anonymous namespace
363
365 BumpPtrAllocator &Allocator, const Function &F,
366 const TargetSubtargetInfo *STI) const {
367 return WebAssemblyFunctionInfo::create<WebAssemblyFunctionInfo>(Allocator, F,
368 STI);
369}
370
374}
375
378 return new WebAssemblyPassConfig(*this, PM);
379}
380
381FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(bool) {
382 return nullptr; // No reg alloc
383}
384
390
392
393 // You can't enable two modes of EH at the same time
394 if (WasmEnableEmEH && WasmEnableEH)
396 "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-eh");
397 // You can't enable two modes of SjLj at the same time
398 if (WasmEnableEmSjLj && WasmEnableSjLj)
400 "-enable-emscripten-sjlj not allowed with -wasm-enable-sjlj");
401 // You can't mix Emscripten EH with Wasm SjLj.
402 if (WasmEnableEmEH && WasmEnableSjLj)
404 "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-sjlj");
405 if (WasmEnableExnref && !WasmEnableEH)
407 "-wasm-enable-exnref should be used with -wasm-enable-eh");
408
409 // Here we make sure TargetOptions.ExceptionModel is the same as
410 // MCAsmInfo.ExceptionsType. Normally these have to be the same, because clang
411 // stores the exception model info in LangOptions, which is later transferred
412 // to TargetOptions and MCAsmInfo. But when clang compiles bitcode directly,
413 // clang's LangOptions is not used and thus the exception model info is not
414 // correctly transferred to TargetOptions and MCAsmInfo, so we make sure we
415 // have the correct exception model in WebAssemblyMCAsmInfo constructor. But
416 // in this case TargetOptions is still not updated, so we make sure they are
417 // the same.
418 TM->Options.ExceptionModel = TM->getMCAsmInfo()->getExceptionHandlingType();
419
420 // Basic Correctness checking related to -exception-model
421 if (TM->Options.ExceptionModel != ExceptionHandling::None &&
422 TM->Options.ExceptionModel != ExceptionHandling::Wasm)
423 report_fatal_error("-exception-model should be either 'none' or 'wasm'");
424 if (WasmEnableEmEH && TM->Options.ExceptionModel == ExceptionHandling::Wasm)
425 report_fatal_error("-exception-model=wasm not allowed with "
426 "-enable-emscripten-cxx-exceptions");
427 if (WasmEnableEH && TM->Options.ExceptionModel != ExceptionHandling::Wasm)
429 "-wasm-enable-eh only allowed with -exception-model=wasm");
430 if (WasmEnableSjLj && TM->Options.ExceptionModel != ExceptionHandling::Wasm)
432 "-wasm-enable-sjlj only allowed with -exception-model=wasm");
433 if ((!WasmEnableEH && !WasmEnableSjLj) &&
434 TM->Options.ExceptionModel == ExceptionHandling::Wasm)
436 "-exception-model=wasm only allowed with at least one of "
437 "-wasm-enable-eh or -wasm-enable-sjlj");
438
439 // Currently it is allowed to mix Wasm EH with Emscripten SjLj as an interim
440 // measure, but some code will error out at compile time in this combination.
441 // See WebAssemblyLowerEmscriptenEHSjLj pass for details.
442}
443
444//===----------------------------------------------------------------------===//
445// The following functions are called from lib/CodeGen/Passes.cpp to modify
446// the CodeGen pass sequence.
447//===----------------------------------------------------------------------===//
448
449void WebAssemblyPassConfig::addIRPasses() {
450 // Add signatures to prototype-less function declarations
452
453 // Lower .llvm.global_dtors into .llvm.global_ctors with __cxa_atexit calls.
455
456 // Fix function bitcasts, as WebAssembly requires caller and callee signatures
457 // to match.
459
460 // Optimize "returned" function attributes.
461 if (getOptLevel() != CodeGenOptLevel::None)
463
465
466 // If exception handling is not enabled and setjmp/longjmp handling is
467 // enabled, we lower invokes into calls and delete unreachable landingpad
468 // blocks. Lowering invokes when there is no EH support is done in
469 // TargetPassConfig::addPassesToHandleExceptions, but that runs after these IR
470 // passes and Emscripten SjLj handling expects all invokes to be lowered
471 // before.
472 if (!WasmEnableEmEH && !WasmEnableEH) {
473 addPass(createLowerInvokePass());
474 // The lower invoke pass may create unreachable code. Remove it in order not
475 // to process dead blocks in setjmp/longjmp handling.
477 }
478
479 // Handle exceptions and setjmp/longjmp if enabled. Unlike Wasm EH preparation
480 // done in WasmEHPrepare pass, Wasm SjLj preparation shares libraries and
481 // transformation algorithms with Emscripten SjLj, so we run
482 // LowerEmscriptenEHSjLj pass also when Wasm SjLj is enabled.
483 if (WasmEnableEmEH || WasmEnableEmSjLj || WasmEnableSjLj)
485
486 // Expand indirectbr instructions to switches.
488
490}
491
492void WebAssemblyPassConfig::addISelPrepare() {
493 // We need to move reference type allocas to WASM_ADDRESS_SPACE_VAR so that
494 // loads and stores are promoted to local.gets/local.sets.
496 // Lower atomics and TLS if necessary
497 addPass(new CoalesceFeaturesAndStripAtomics(&getWebAssemblyTargetMachine()));
498
499 // This is a no-op if atomics are not used in the module
501
503}
504
505bool WebAssemblyPassConfig::addInstSelector() {
507 addPass(
508 createWebAssemblyISelDag(getWebAssemblyTargetMachine(), getOptLevel()));
509 // Run the argument-move pass immediately after the ScheduleDAG scheduler
510 // so that we can fix up the ARGUMENT instructions before anything else
511 // sees them in the wrong place.
513 // Set the p2align operands. This information is present during ISel, however
514 // it's inconvenient to collect. Collect it now, and update the immediate
515 // operands.
517
518 // Eliminate range checks and add default targets to br_table instructions.
520
521 // unreachable is terminator, non-terminator instruction after it is not
522 // allowed.
524
525 return false;
526}
527
528void WebAssemblyPassConfig::addOptimizedRegAlloc() {
529 // Currently RegisterCoalesce degrades wasm debug info quality by a
530 // significant margin. As a quick fix, disable this for -O1, which is often
531 // used for debugging large applications. Disabling this increases code size
532 // of Emscripten core benchmarks by ~5%, which is acceptable for -O1, which is
533 // usually not used for production builds.
534 // TODO Investigate why RegisterCoalesce degrades debug info quality and fix
535 // it properly
536 if (getOptLevel() == CodeGenOptLevel::Less)
537 disablePass(&RegisterCoalescerID);
539}
540
541void WebAssemblyPassConfig::addPostRegAlloc() {
542 // TODO: The following CodeGen passes don't currently support code containing
543 // virtual registers. Consider removing their restrictions and re-enabling
544 // them.
545
546 // These functions all require the NoVRegs property.
547 disablePass(&MachineLateInstrsCleanupID);
548 disablePass(&MachineCopyPropagationID);
549 disablePass(&PostRAMachineSinkingID);
550 disablePass(&PostRASchedulerID);
551 disablePass(&FuncletLayoutID);
552 disablePass(&StackMapLivenessID);
553 disablePass(&PatchableFunctionID);
554 disablePass(&ShrinkWrapID);
555
556 // This pass hurts code size for wasm because it can generate irreducible
557 // control flow.
558 disablePass(&MachineBlockPlacementID);
559
561}
562
563void WebAssemblyPassConfig::addPreEmitPass() {
565
566 // Nullify DBG_VALUE_LISTs that we cannot handle.
568
569 // Eliminate multiple-entry loops.
572
573 // Do various transformations for exception handling.
574 // Every CFG-changing optimizations should come before this.
575 if (TM->Options.ExceptionModel == ExceptionHandling::Wasm)
577
578 // Now that we have a prologue and epilogue and all frame indices are
579 // rewritten, eliminate SP and FP. This allows them to be stackified,
580 // colored, and numbered with the rest of the registers.
582
583 // Preparations and optimizations related to register stackification.
584 if (getOptLevel() != CodeGenOptLevel::None) {
585 // Depend on LiveIntervals and perform some optimizations on it.
587
588 // Prepare memory intrinsic calls for register stackifying.
590
591 // Mark registers as representing wasm's value stack. This is a key
592 // code-compression technique in WebAssembly. We run this pass (and
593 // MemIntrinsicResults above) very late, so that it sees as much code as
594 // possible, including code emitted by PEI and expanded by late tail
595 // duplication.
597
598 // Run the register coloring pass to reduce the total number of registers.
599 // This runs after stackification so that it doesn't consider registers
600 // that become stackified.
602 }
603
604 // Sort the blocks of the CFG into topological order, a prerequisite for
605 // BLOCK and LOOP markers.
606 addPass(createWebAssemblyCFGSort());
607
608 // Insert BLOCK and LOOP markers.
610
611 // Insert explicit local.get and local.set operators.
614
615 // Lower br_unless into br_if.
617
618 // Perform the very last peephole optimizations on the code.
619 if (getOptLevel() != CodeGenOptLevel::None)
620 addPass(createWebAssemblyPeephole());
621
622 // Create a mapping from LLVM CodeGen virtual registers to wasm registers.
624
625 // Fix debug_values whose defs have been stackified.
628
629 // Collect information to prepare for MC lowering / asm printing.
631}
632
633bool WebAssemblyPassConfig::addPreISel() {
636 return false;
637}
638
642}
643
645 const MachineFunction &MF) const {
646 const auto *MFI = MF.getInfo<WebAssemblyFunctionInfo>();
647 return new yaml::WebAssemblyFunctionInfo(MF, *MFI);
648}
649
652 SMDiagnostic &Error, SMRange &SourceRange) const {
653 const auto &YamlMFI = static_cast<const yaml::WebAssemblyFunctionInfo &>(MFI);
654 MachineFunction &MF = PFS.MF;
655 MF.getInfo<WebAssemblyFunctionInfo>()->initializeBaseYamlFields(MF, YamlMFI);
656 return false;
657}
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:131
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.
static Reloc::Model getEffectiveRelocModel(std::optional< Reloc::Model > RM, const Triple &TT)
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))
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 TargetTransformInfo::Concept 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:253
StringRef getValueAsString() const
Return the attribute's value as a string.
Definition: Attributes.cpp:392
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition: Attributes.h:203
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:66
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
Container class for subtarget features.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:310
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:48
This class describes a target machine that is implemented with the LLVM target-independent code gener...
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:251
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
static 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:281
Represents a range in source code.
Definition: SMLoc.h:48
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:215
Manages the enabling and disabling of subtarget specific features.
static bool isEnabled(StringRef Feature)
Return true if enable flag; '+'.
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
Triple TargetTriple
Triple string, CPU name, and target feature strings the TargetMachine instance is created with.
Definition: TargetMachine.h:96
std::string TargetFS
Definition: TargetMachine.h:98
StringRef getTargetFeatureString() const
StringRef getTargetCPU() const
std::string TargetCPU
Definition: TargetMachine.h:97
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:44
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
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 > WasmEnableEH
cl::opt< bool > WasmEnableSjLj
cl::opt< bool > WasmEnableExnref
cl::opt< bool > WasmEnableEmEH
cl::opt< bool > WasmEnableEmSjLj
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
@ WASM_FEATURE_PREFIX_USED
Definition: Wasm.h:169
@ WASM_FEATURE_PREFIX_DISALLOWED
Definition: Wasm.h:171
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void initializeOptimizeReturnedPass(PassRegistry &)
FunctionPass * createIndirectBrExpandPass()
void initializeWebAssemblyLowerBrUnlessPass(PassRegistry &)
FunctionPass * createWebAssemblyLowerRefTypesIntPtrConv()
FunctionPass * createWebAssemblyRegNumbering()
FunctionPass * createUnreachableBlockEliminationPass()
createUnreachableBlockEliminationPass - The LLVM code generator does not work well with unreachable b...
ModulePass * createWebAssemblyAddMissingPrototypes()
char & RegisterCoalescerID
RegisterCoalescer - This pass merges live ranges to eliminate copies.
FunctionPass * createWebAssemblyLateEHPrepare()
const SubtargetFeatureKV WebAssemblyFeatureKV[WebAssembly::NumSubtargetFeatures]
void initializeWebAssemblyLateEHPreparePass(PassRegistry &)
@ None
No exception support.
@ 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:656
char & PatchableFunctionID
This pass implements the "patchable-function" attribute.
void initializeWebAssemblyExceptionInfoPass(PassRegistry &)
char & PostRASchedulerID
PostRAScheduler - This pass performs post register allocation scheduling.
void initializeWebAssemblyRegNumberingPass(PassRegistry &)
void initializeWebAssemblyLowerRefTypesIntPtrConvPass(PassRegistry &)
void initializeWebAssemblyDAGToDAGISelLegacyPass(PassRegistry &)
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()
char & ShrinkWrapID
ShrinkWrap pass. Look for the best place to insert save and restore.
Definition: ShrinkWrap.cpp:288
char & MachineLateInstrsCleanupID
MachineLateInstrsCleanup - This pass removes redundant identical instructions after register allocati...
FunctionPass * createWebAssemblyDebugFixup()
ModulePass * createLowerGlobalDtorsLegacyPass()
FunctionPass * createLowerInvokePass()
Definition: LowerInvoke.cpp:85
void initializeLowerGlobalDtorsLegacyPassPass(PassRegistry &)
Target & getTheWebAssemblyTarget32()
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
void initializeWebAssemblyNullifyDebugValueListsPass(PassRegistry &)
char & StackMapLivenessID
StackMapLiveness - This pass analyses the register live-out set of stackmap/patchpoint intrinsics and...
void initializeWebAssemblyFixIrreducibleControlFlowPass(PassRegistry &)
FunctionPass * createWebAssemblyISelDag(WebAssemblyTargetMachine &TM, CodeGenOptLevel OptLevel)
This pass converts a legalized DAG into a WebAssembly-specific DAG, ready for instruction scheduling.
char & FuncletLayoutID
This pass lays out funclets contiguously.
void initializeWebAssemblyRegStackifyPass(PassRegistry &)
FunctionPass * createWebAssemblyCFGStackify()
FunctionPass * createWebAssemblyOptimizeLiveIntervals()
char & PostRAMachineSinkingID
This pass perform post-ra machine sink for COPY instructions.
CodeGenOptLevel
Code generation optimization level.
Definition: CodeGen.h:54
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 &)
char & MachineBlockPlacementID
MachineBlockPlacement - This pass places basic blocks based on branch probabilities.
FunctionPass * createAtomicExpandLegacyPass()
AtomicExpandPass - At IR level this pass replace atomic instructions with __atomic_* library calls,...
FunctionPass * createWebAssemblyRegStackify()
FunctionPass * createWebAssemblyCFGSort()
void initializeWebAssemblyCFGSortPass(PassRegistry &)
void initializeWebAssemblyFixBrTableDefaultsPass(PassRegistry &)
FunctionPass * createWebAssemblyNullifyDebugValueLists()
void initializeWebAssemblyCFGStackifyPass(PassRegistry &)
void initializeWebAssemblySetP2AlignOperandsPass(PassRegistry &)
void initializeWebAssemblyDebugFixupPass(PassRegistry &)
char & MachineCopyPropagationID
MachineCopyPropagation - This pass performs copy propagation on machine instructions.
void initializeWebAssemblyArgumentMovePass(PassRegistry &)
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.