39#define DEBUG_TYPE "wasm"
47 cl::desc(
"WebAssembly: output implicit locals in"
48 " instruction output for test purposes only."),
114 ? (TT.isOSEmscripten() ?
"e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-"
115 "f128:64-n32:64-S128-ni:1:10:20"
116 :
"e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-"
117 "n32:64-S128-ni:1:10:20")
118 : (TT.isOSEmscripten() ?
"e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-"
119 "f128:64-n32:64-S128-ni:1:10:20"
120 :
"e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-"
121 "n32:64-S128-ni:1:10:20"),
153 std::string FS)
const {
154 auto &
I = SubtargetMap[CPU + FS];
156 I = std::make_unique<WebAssemblySubtarget>(
TargetTriple, CPU, FS, *
this);
163 Attribute CPUAttr =
F.getFnAttribute(
"target-cpu");
164 Attribute FSAttr =
F.getFnAttribute(
"target-features");
181class CoalesceFeaturesAndStripAtomics final :
public ModulePass {
193 bool runOnModule(
Module &M)
override {
196 std::string FeatureStr = getFeatureString(Features);
199 replaceFeatures(
F, FeatureStr);
201 bool StrippedAtomics =
false;
202 bool StrippedTLS =
false;
204 if (!Features[WebAssembly::FeatureAtomics]) {
205 StrippedAtomics = stripAtomics(M);
206 StrippedTLS = stripThreadLocals(M);
207 }
else if (!Features[WebAssembly::FeatureBulkMemory]) {
208 StrippedTLS |= stripThreadLocals(M);
211 if (StrippedAtomics && !StrippedTLS)
212 stripThreadLocals(M);
213 else if (StrippedTLS && !StrippedAtomics)
216 recordFeatures(M, Features, StrippedAtomics || StrippedTLS);
234 std::string getFeatureString(
const FeatureBitset &Features) {
237 if (Features[KV.Value])
243 void replaceFeatures(
Function &
F,
const std::string &Features) {
244 F.removeFnAttr(
"target-features");
245 F.removeFnAttr(
"target-cpu");
246 F.addFnAttr(
"target-features", Features);
249 bool stripAtomics(
Module &M) {
252 bool Stripped =
false;
276 bool stripThreadLocals(
Module &M) {
277 bool Stripped =
false;
278 for (
auto &GV :
M.globals()) {
279 if (GV.isThreadLocal()) {
281 GV.setThreadLocal(
false);
289 if (Features[KV.Value]) {
291 std::string MDKey = (
StringRef(
"wasm-feature-") + KV.Key).str();
292 M.addModuleFlag(Module::ModFlagBehavior::Error, MDKey,
302 M.addModuleFlag(Module::ModFlagBehavior::Error,
"wasm-feature-shared-mem",
307char CoalesceFeaturesAndStripAtomics::ID = 0;
316 return getTM<WebAssemblyTargetMachine>();
319 FunctionPass *createTargetRegisterAllocator(
bool)
override;
321 void addIRPasses()
override;
322 void addISelPrepare()
override;
323 bool addInstSelector()
override;
324 void addOptimizedRegAlloc()
override;
325 void addPostRegAlloc()
override;
326 bool addGCPasses()
override {
return false; }
327 void addPreEmitPass()
override;
328 bool addPreISel()
override;
331 bool addRegAssignAndRewriteFast()
override {
return false; }
334 bool addRegAssignAndRewriteOptimized()
override {
return false; }
341 return WebAssemblyFunctionInfo::create<WebAssemblyFunctionInfo>(
Allocator,
F,
352 return new WebAssemblyPassConfig(*
this, PM);
355FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(
bool) {
374 TM->Options.ExceptionModel =
TM->getMCAsmInfo()->getExceptionHandlingType();
382 "-enable-emscripten-cxx-exceptions");
385 "-wasm-enable-eh only allowed with -exception-model=wasm");
388 "-wasm-enable-sjlj only allowed with -exception-model=wasm");
389 if ((!WasmEnableEH && !WasmEnableSjLj) &&
392 "-exception-model=wasm only allowed with at least one of "
393 "-wasm-enable-eh or -wasm-enable-sjj");
396 if (WasmEnableEmEH && WasmEnableEH)
398 "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-eh");
400 if (WasmEnableEmSjLj && WasmEnableSjLj)
402 "-enable-emscripten-sjlj not allowed with -wasm-enable-sjlj");
404 if (WasmEnableEmEH && WasmEnableSjLj)
406 "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-sjlj");
417void WebAssemblyPassConfig::addIRPasses() {
440 if (!WasmEnableEmEH && !WasmEnableEH) {
451 if (WasmEnableEmEH || WasmEnableEmSjLj || WasmEnableSjLj)
460void WebAssemblyPassConfig::addISelPrepare() {
471 addPass(
new CoalesceFeaturesAndStripAtomics(&getWebAssemblyTargetMachine()));
479bool WebAssemblyPassConfig::addInstSelector() {
498void WebAssemblyPassConfig::addOptimizedRegAlloc() {
511void WebAssemblyPassConfig::addPostRegAlloc() {
533void WebAssemblyPassConfig::addPreEmitPass() {
602bool WebAssemblyPassConfig::addPreISel() {
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
FunctionAnalysisManager FAM
const char LLVMTargetMachineRef TM
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))
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.
A container for analyses that lazily runs them and caches their results.
StringRef getValueAsString() const
Return the attribute's value as a string.
bool isValid() const
Return true if the attribute is any kind of attribute.
Allocate memory in an ever growing pool, as if by bump-pointer.
Lightweight error class with error context and mandatory checking.
Container class for subtarget features.
FunctionPass class - This class is used to implement most global optimizations.
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...
A Module instance is used to store all the information related to an LLVM module.
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...
Represents a range in source code.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - 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)
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 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.
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 ...
bool hasReferenceTypes() const
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 > 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.
void initializeOptimizeReturnedPass(PassRegistry &)
FunctionPass * createIndirectBrExpandPass()
void initializeWebAssemblyLowerBrUnlessPass(PassRegistry &)
void initializeWebAssemblyDAGToDAGISelPass(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 * createAtomicExpandPass()
AtomicExpandPass - At IR level this pass replace atomic instructions with __atomic_* library calls,...
FunctionPass * createWebAssemblyFixBrTableDefaults()
void initializeWebAssemblyAddMissingPrototypesPass(PassRegistry &)
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 &)
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.
char & MachineLateInstrsCleanupID
MachineLateInstrsCleanup - This pass removes redundant identical instructions after register allocati...
FunctionPass * createWebAssemblyDebugFixup()
ModulePass * createLowerGlobalDtorsLegacyPass()
FunctionPass * createLowerInvokePass()
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.
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.
FunctionPass * createWebAssemblyOptimizeReturned()
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()
char & MachineBlockPlacementID
MachineBlockPlacement - This pass places basic blocks based on branch probabilities.
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()
FunctionPass * createPromoteMemoryToRegisterPass(bool IsForced=false)
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.