42#define DEBUG_TYPE "wasm"
50 cl::desc(
"WebAssembly: output implicit locals in"
51 " instruction output for test purposes only."),
58 "enable-emscripten-cxx-exceptions",
59 cl::desc(
"WebAssembly Emscripten-style exception handling"),
63 "enable-emscripten-sjlj",
64 cl::desc(
"WebAssembly Emscripten-style setjmp/longjmp handling"),
69 cl::desc(
"WebAssembly exception handling"));
72 "wasm-enable-sjlj",
cl::desc(
"WebAssembly setjmp/longjmp handling"));
80 "wasm-use-legacy-eh",
cl::desc(
"WebAssembly exception handling (legacy)"),
145 if (WasmEnableEmEH && WasmEnableEH)
147 "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-eh");
149 if (WasmEnableEmSjLj && WasmEnableSjLj)
151 "-enable-emscripten-sjlj not allowed with -wasm-enable-sjlj");
153 if (WasmEnableEmEH && WasmEnableSjLj)
155 "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-sjlj");
170 "-enable-emscripten-cxx-exceptions");
173 "-wasm-enable-eh only allowed with -exception-model=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");
198 UsesMultivalueABI(
Options.MCOptions.getABIName() ==
"experimental-mv") {
234 std::string FS)
const {
235 auto &
I = SubtargetMap[CPU + FS];
237 I = std::make_unique<WebAssemblySubtarget>(
TargetTriple, CPU, FS, *
this);
244 Attribute CPUAttr =
F.getFnAttribute(
"target-cpu");
245 Attribute FSAttr =
F.getFnAttribute(
"target-features");
257class CoalesceFeaturesAndStripAtomics final :
public ModulePass {
269 bool runOnModule(
Module &M)
override {
270 auto [Features, FeatureStr] = coalesceFeatures(M);
274 replaceFeatures(
F, FeatureStr);
276 bool StrippedAtomics =
false;
277 bool StrippedTLS =
false;
282 bool CooperativeThreading = ST->hasCooperativeMultithreading();
284 if (!Features[WebAssembly::FeatureAtomics]) {
285 StrippedAtomics = stripAtomics(M);
286 if (!CooperativeThreading)
287 StrippedTLS = stripThreadLocals(M);
289 if (!Features[WebAssembly::FeatureBulkMemory] && !StrippedTLS) {
290 StrippedTLS = stripThreadLocals(M);
293 if (StrippedAtomics && !StrippedTLS && !CooperativeThreading)
294 stripThreadLocals(M);
295 else if (StrippedTLS && !StrippedAtomics)
298 recordFeatures(M, ST, Features, StrippedAtomics || StrippedTLS);
305 std::pair<FeatureBitset, std::string> coalesceFeatures(
const Module &M) {
310 FeatureBitset Features;
312 const WebAssemblySubtarget *AnyST =
nullptr;
314 if (
F.isDeclaration())
318 Features |= AnyST->getFeatureBits();
327 Features = AnyST->getFeatureBits();
330 return {Features, getFeatureString(AnyST, Features)};
333 static std::string getFeatureString(
const WebAssemblySubtarget *ST,
334 const FeatureBitset &Features) {
336 for (
const SubtargetFeatureKV &KV :
ST->getAllProcessorFeatures()) {
337 if (Features[KV.Value])
338 Ret += (StringRef(
"+") + KV.key() +
",").str();
340 Ret += (StringRef(
"-") + KV.key() +
",").str();
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);
353 bool stripAtomics(
Module &M) {
356 bool Stripped =
false;
372 LowerAtomicPass Lowerer;
380 bool stripThreadLocals(
Module &M) {
381 bool Stripped =
false;
382 for (
auto &GV :
M.globals()) {
383 if (GV.isThreadLocal()) {
387 if (
II->getIntrinsicID() == Intrinsic::threadlocal_address &&
388 II->getArgOperand(0) == &GV) {
389 II->replaceAllUsesWith(&GV);
390 II->eraseFromParent();
396 GV.setThreadLocal(
false);
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]) {
407 std::string MDKey = (StringRef(
"wasm-feature-") + KV.key()).str();
408 M.addModuleFlag(Module::ModFlagBehavior::Error, MDKey,
418 M.addModuleFlag(Module::ModFlagBehavior::Error,
"wasm-feature-shared-mem",
423char CoalesceFeaturesAndStripAtomics::ID = 0;
428 WebAssemblyPassConfig(WebAssemblyTargetMachine &TM, PassManagerBase &PM)
429 : TargetPassConfig(TM, PM) {}
431 WebAssemblyTargetMachine &getWebAssemblyTargetMachine()
const {
435 FunctionPass *createTargetRegisterAllocator(
bool)
override;
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;
447 bool addRegAssignAndRewriteFast()
override {
return false; }
450 bool addRegAssignAndRewriteOptimized()
override {
return false; }
452 bool addIRTranslator()
override;
453 void addPreLegalizeMachineIR()
override;
454 bool addLegalizeMachineIR()
override;
455 void addPreRegBankSelect()
override;
456 bool addRegBankSelect()
override;
457 bool addGlobalInstructionSelect()
override;
475 return new WebAssemblyPassConfig(*
this, PM);
478FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(
bool) {
487void WebAssemblyPassConfig::addIRPasses() {
508 if (!WasmEnableEmEH && !WasmEnableEH) {
519 if (WasmEnableEmEH || WasmEnableEmSjLj || WasmEnableSjLj)
531void WebAssemblyPassConfig::addISelPrepare() {
536 addPass(
new CoalesceFeaturesAndStripAtomics(&getWebAssemblyTargetMachine()));
544bool WebAssemblyPassConfig::addInstSelector() {
567void WebAssemblyPassConfig::addOptimizedRegAlloc() {
580void WebAssemblyPassConfig::addPostRegAlloc() {
603void WebAssemblyPassConfig::addPreEmitPass() {
678bool WebAssemblyPassConfig::addPreISel() {
683bool WebAssemblyPassConfig::addIRTranslator() {
688void WebAssemblyPassConfig::addPreLegalizeMachineIR() {
693bool WebAssemblyPassConfig::addLegalizeMachineIR() {
698void WebAssemblyPassConfig::addPreRegBankSelect() {
704bool WebAssemblyPassConfig::addRegBankSelect() {
709bool WebAssemblyPassConfig::addGlobalInstructionSelect() {
713 if (isGlobalISelAbortEnabled()) {
static Reloc::Model getEffectiveRelocModel()
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
This file declares the IRTranslator pass.
Machine Check Debug Module
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 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...
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.
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.
FunctionPass class - This class is used to implement most global optimizations.
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...
A Module instance is used to store all the information related to an LLVM module.
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...
Represents a range in source code.
Represent a constant reference to a string, i.e.
std::string str() const
Get the contents as an std::string.
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
void setTargetFeatureString(StringRef FS)
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.
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.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
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.
~WebAssemblyTargetMachine() override
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.
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
@ WASM_FEATURE_PREFIX_DISALLOWED
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.
void initializeWebAssemblyPostLegalizerCombinerPass(PassRegistry &)
void initializeWebAssemblyLateEHPreparePass(PassRegistry &)
@ None
No exception support.
@ Wasm
WebAssembly Exception Handling.
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...
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)
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.
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.
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.