Go to the documentation of this file.
37 #define DEBUG_TYPE "wasm"
45 cl::desc(
"WebAssembly: output implicit locals in"
46 " instruction output for test purposes only."),
97 if (!TT.isOSEmscripten()) {
116 ? (TT.isOSEmscripten() ?
"e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-"
117 "f128:64-n32:64-S128-ni:1:10:20"
118 :
"e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-"
119 "n32:64-S128-ni:1:10:20")
120 : (TT.isOSEmscripten() ?
"e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-"
121 "f128:64-n32:64-S128-ni:1:10:20"
122 :
"e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-"
123 "n32:64-S128-ni:1:10:20"),
155 std::string
FS)
const {
156 auto &
I = SubtargetMap[CPU +
FS];
158 I = std::make_unique<WebAssemblySubtarget>(
TargetTriple, CPU,
FS, *
this);
165 Attribute CPUAttr =
F.getFnAttribute(
"target-cpu");
166 Attribute FSAttr =
F.getFnAttribute(
"target-features");
183 class CoalesceFeaturesAndStripAtomics final :
public ModulePass {
195 bool runOnModule(
Module &M)
override {
198 std::string FeatureStr = getFeatureString(Features);
201 replaceFeatures(
F, FeatureStr);
203 bool StrippedAtomics =
false;
204 bool StrippedTLS =
false;
206 if (!Features[WebAssembly::FeatureAtomics]) {
207 StrippedAtomics = stripAtomics(M);
208 StrippedTLS = stripThreadLocals(M);
209 }
else if (!Features[WebAssembly::FeatureBulkMemory]) {
210 StrippedTLS |= stripThreadLocals(M);
213 if (StrippedAtomics && !StrippedTLS)
214 stripThreadLocals(M);
215 else if (StrippedTLS && !StrippedAtomics)
218 recordFeatures(M, Features, StrippedAtomics || StrippedTLS);
236 std::string getFeatureString(
const FeatureBitset &Features) {
239 if (Features[KV.Value])
245 void replaceFeatures(
Function &
F,
const std::string &Features) {
246 F.removeFnAttr(
"target-features");
247 F.removeFnAttr(
"target-cpu");
248 F.addFnAttr(
"target-features", Features);
251 bool stripAtomics(
Module &M) {
254 bool Stripped =
false;
278 bool stripThreadLocals(
Module &M) {
279 bool Stripped =
false;
280 for (
auto &GV :
M.globals()) {
281 if (GV.isThreadLocal()) {
283 GV.setThreadLocal(
false);
291 if (Features[KV.Value]) {
293 std::string MDKey = (
StringRef(
"wasm-feature-") + KV.Key).str();
318 return getTM<WebAssemblyTargetMachine>();
321 FunctionPass *createTargetRegisterAllocator(
bool)
override;
323 void addIRPasses()
override;
324 void addISelPrepare()
override;
325 bool addInstSelector()
override;
326 void addPostRegAlloc()
override;
327 bool addGCPasses()
override {
return false; }
328 void addPreEmitPass()
override;
329 bool addPreISel()
override;
332 bool addRegAssignAndRewriteFast()
override {
return false; }
335 bool addRegAssignAndRewriteOptimized()
override {
return false; }
346 return new WebAssemblyPassConfig(*
this, PM);
349 FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(
bool) {
368 TM->Options.ExceptionModel =
TM->getMCAsmInfo()->getExceptionHandlingType();
376 "-enable-emscripten-cxx-exceptions");
379 "-wasm-enable-eh only allowed with -exception-model=wasm");
382 "-wasm-enable-sjlj only allowed with -exception-model=wasm");
386 "-exception-model=wasm only allowed with at least one of "
387 "-wasm-enable-eh or -wasm-enable-sjj");
392 "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-eh");
396 "-enable-emscripten-sjlj not allowed with -wasm-enable-sjlj");
400 "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-sjlj");
411 void WebAssemblyPassConfig::addIRPasses() {
454 void WebAssemblyPassConfig::addISelPrepare() {
456 addPass(
new CoalesceFeaturesAndStripAtomics(&getWebAssemblyTargetMachine()));
464 bool WebAssemblyPassConfig::addInstSelector() {
483 void WebAssemblyPassConfig::addPostRegAlloc() {
505 void WebAssemblyPassConfig::addPreEmitPass() {
574 bool WebAssemblyPassConfig::addPreISel() {
virtual void addPostRegAlloc()
This method may be implemented by targets that want to run passes after register allocation pass pipe...
@ WASM_FEATURE_PREFIX_DISALLOWED
const SubtargetFeatureKV WebAssemblyFeatureKV[WebAssembly::NumSubtargetFeatures]
FunctionPass * createLowerInvokePass()
This is an optimization pass for GlobalISel generic memory operations.
bool isValid() const
Return true if the attribute is any kind of attribute.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
void initializeWebAssemblyCFGStackifyPass(PassRegistry &)
A pass that lowers atomic intrinsic into non-atomic intrinsics.
Target & getTheWebAssemblyTarget32()
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
FunctionPass * createWebAssemblyReplacePhysRegs()
Targets should override this in a way that mirrors the implementation of llvm::MachineFunctionInfo.
FunctionPass * createWebAssemblyExplicitLocals()
void initializeLowerGlobalDtorsLegacyPassPass(PassRegistry &)
Target - Wrapper for Target specific information.
FunctionPass * createWebAssemblyISelDag(WebAssemblyTargetMachine &TM, CodeGenOpt::Level OptLevel)
This pass converts a legalized DAG into a WebAssembly-specific DAG, ready for instruction scheduling.
~WebAssemblyTargetMachine() override
Triple - Helper class for working with autoconf configuration names.
FunctionAnalysisManager FAM
FunctionPass * createWebAssemblyRegColoring()
unsigned TrapUnreachable
Emit target-specific trap instruction for 'unreachable' IR instructions.
FunctionPass * createWebAssemblyCFGStackify()
void initializeWebAssemblySetP2AlignOperandsPass(PassRegistry &)
Container class for subtarget features.
ModulePass * createLowerGlobalDtorsLegacyPass()
void initializeWebAssemblyLowerEmscriptenEHSjLjPass(PassRegistry &)
TargetPassConfig * createPassConfig(PassManagerBase &PM) override
Create a pass configuration object to be used by addPassToEmitX methods for generating a pipeline of ...
char & MachineCopyPropagationID
MachineCopyPropagation - This pass performs copy propagation on machine instructions.
FunctionPass * createUnreachableBlockEliminationPass()
createUnreachableBlockEliminationPass - The LLVM code generator does not work well with unreachable b...
void initializeWebAssemblyRegStackifyPass(PassRegistry &)
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM ID Predecessors according to mbb< bb27, 0x8b0a7c0 > Note ADDri is not a two address instruction its result reg1037 is an operand of the PHI node in bb76 and its operand reg1039 is the result of the PHI node We should treat it as a two address code and make sure the ADDri is scheduled after any node that reads reg1039 Use info(i.e. register scavenger) to assign it a free register to allow reuse the collector could move the objects and invalidate the derived pointer This is bad enough in the first but safe points can crop up unpredictably **array_addr i32 n y store obj * new
yaml::MachineFunctionInfo * convertFuncInfoToYAML(const MachineFunction &MF) const override
Allocate and initialize an instance of the YAML representation of the MachineFunctionInfo.
void initializeWebAssemblyCFGSortPass(PassRegistry &)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyTarget()
FunctionPass * createWebAssemblyFixIrreducibleControlFlow()
virtual bool addInstSelector()
addInstSelector - This method should install an instruction selector pass, which converts from LLVM c...
FunctionPass * createWebAssemblyFixBrTableDefaults()
char & LiveDebugValuesID
LiveDebugValues pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
unsigned UniqueSectionNames
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
char & FuncletLayoutID
This pass lays out funclets contiguously.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
cl::opt< bool > WasmEnableEmSjLj
FunctionPass * createWebAssemblyRegStackify()
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
FunctionPass * createAtomicExpandPass()
AtomicExpandPass - At IR level this pass replace atomic instructions with __atomic_* library calls,...
RegisterTargetMachine - Helper template for registering a target machine implementation,...
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
@ Wasm
WebAssembly Exception Handling.
void initializeWebAssemblyAddMissingPrototypesPass(PassRegistry &)
void initializeWebAssemblyOptimizeLiveIntervalsPass(PassRegistry &)
ModulePass * createWebAssemblyLowerEmscriptenEHSjLj()
char & StackMapLivenessID
StackMapLiveness - This pass analyses the register live-out set of stackmap/patchpoint intrinsics and...
FunctionPass * createWebAssemblyOptimizeLiveIntervals()
void initializeWebAssemblyExceptionInfoPass(PassRegistry &)
Used to provide key value pairs for feature and CPU bit flags.
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
StringRef getValueAsString() const
Return the attribute's value as a string.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
void resetTargetOptions(const Function &F) const
Reset the target options based on the function's attributes.
Target-Independent Code Generator Pass Configuration Options.
const WebAssemblySubtarget * getSubtargetImpl() const
Triple TargetTriple
Triple string, CPU name, and target feature strings the TargetMachine instance is created with.
yaml::MachineFunctionInfo * createDefaultFuncInfoYAML() const override
Allocate and return a default initialized instance of the YAML representation for the MachineFunction...
ModulePass * createWebAssemblyMCLowerPrePass()
void initializeWebAssemblyFixIrreducibleControlFlowPass(PassRegistry &)
FunctionPass * createWebAssemblyDebugFixup()
void initializeWebAssemblyMCLowerPrePassPass(PassRegistry &)
@ WASM_FEATURE_PREFIX_USED
void initializeWebAssemblyRegNumberingPass(PassRegistry &)
#define LLVM_EXTERNAL_VISIBILITY
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))
virtual void addIRPasses()
Add common target configurable passes that perform LLVM IR to IR transforms following machine indepen...
initializer< Ty > init(const Ty &Val)
void initializeWebAssemblyLowerBrUnlessPass(PassRegistry &)
FunctionPass * createWebAssemblyNullifyDebugValueLists()
FunctionPass * createWebAssemblyMemIntrinsicResults()
cl::opt< bool > WasmEnableSjLj
FunctionPass * createWebAssemblyOptimizeReturned()
Primary interface to the complete machine description for the target machine.
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
A Module instance is used to store all the information related to an LLVM module.
bool parseMachineFunctionInfo(const yaml::MachineFunctionInfo &, PerFunctionMIParsingState &PFS, SMDiagnostic &Error, SMRange &SourceRange) const override
Parse out the target's MachineFunctionInfo from the YAML reprsentation.
void setTargetFeatureString(StringRef FS)
ModulePass * createWebAssemblyAddMissingPrototypes()
char & PatchableFunctionID
This pass implements the "patchable-function" attribute.
StringRef - Represent a constant reference to a string, i.e.
static void basicCheckForEHAndSjLj(TargetMachine *TM)
void initializeWebAssemblyExplicitLocalsPass(PassRegistry &)
StringRef getTargetFeatureString() const
char & MachineBlockPlacementID
MachineBlockPlacement - This pass places basic blocks based on branch probabilities.
FunctionPass * createIndirectBrExpandPass()
char & ShrinkWrapID
ShrinkWrap pass. Look for the best place to insert save and restore.
FunctionPass * createWebAssemblyLowerRefTypesIntPtrConv()
TargetTransformInfo getTargetTransformInfo(const Function &F) const override
Get a TargetTransformInfo implementation for the target.
cl::opt< bool > WasmEnableEH
static Reloc::Model getEffectiveRelocModel(Optional< Reloc::Model > RM)
CodeModel::Model getEffectiveCodeModel(Optional< CodeModel::Model > CM, CodeModel::Model Default)
Helper method for getting the code model, returning Default if CM does not have a value.
Target & getTheWebAssemblyTarget64()
FunctionPass * createWebAssemblyCFGSort()
void initializeWebAssemblyRegColoringPass(PassRegistry &)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &)
Lightweight error class with error context and mandatory checking.
void initializeWebAssemblyDebugFixupPass(PassRegistry &)
void initializeWebAssemblyArgumentMovePass(PassRegistry &)
unsigned DataSections
Emit data into separate sections.
This class describes a target machine that is implemented with the LLVM target-independent code gener...
void initializeWebAssemblyLateEHPreparePass(PassRegistry &)
@ None
No exception support.
FunctionPass * createWebAssemblyArgumentMove()
virtual void addISelPrepare()
Add common passes that perform LLVM IR to IR transforms in preparation for instruction selection.
StringRef getTargetCPU() const
char & PostRASchedulerID
PostRAScheduler - This pass performs post register allocation scheduling.
ModulePass * createWebAssemblyFixFunctionBitcasts()
Represents a range in source code.
void initializeWebAssemblyNullifyDebugValueListsPass(PassRegistry &)
FunctionPass * createWebAssemblySetP2AlignOperands()
virtual bool addPreISel()
Methods with trivial inline returns are convenient points in the common codegen pass pipeline where t...
PassManagerBase - An abstract interface to allow code to add passes to a pass manager without having ...
void initializeWebAssemblyPeepholePass(PassRegistry &)
FunctionPass * createWebAssemblyLowerBrUnless()
A container for analyses that lazily runs them and caches their results.
const char LLVMTargetMachineRef TM
FunctionPass class - This class is used to implement most global optimizations.
unsigned FunctionSections
Emit functions into separate sections.
char & PostRAMachineSinkingID
This pass perform post-ra machine sink for COPY instructions.
FunctionPass * createWebAssemblyRegNumbering()
FunctionPass * createWebAssemblyLateEHPrepare()
virtual void addPreEmitPass()
This pass may be implemented by targets that want to run passes immediately before machine code is em...
void initializeOptimizeReturnedPass(PassRegistry &)
void initializeWebAssemblyReplacePhysRegsPass(PassRegistry &)
void initializeWebAssemblyMemIntrinsicResultsPass(PassRegistry &)
FunctionPass * createWebAssemblyPeephole()
void initializeFixFunctionBitcastsPass(PassRegistry &)
cl::opt< bool > WasmEnableEmEH
WebAssemblyTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Optional< Reloc::Model > RM, Optional< CodeModel::Model > CM, CodeGenOpt::Level OL, bool JIT)
Create an WebAssembly architecture model.