LLVM  7.0.0svn
WebAssemblyTargetMachine.cpp
Go to the documentation of this file.
1 //===- WebAssemblyTargetMachine.cpp - Define TargetMachine for WebAssembly -==//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief This file defines the WebAssembly-specific subclass of TargetMachine.
12 ///
13 //===----------------------------------------------------------------------===//
14 
17 #include "WebAssembly.h"
21 #include "llvm/CodeGen/Passes.h"
24 #include "llvm/IR/Function.h"
27 #include "llvm/Transforms/Scalar.h"
28 using namespace llvm;
29 
30 #define DEBUG_TYPE "wasm"
31 
32 // Emscripten's asm.js-style exception handling
34  "enable-emscripten-cxx-exceptions",
35  cl::desc("WebAssembly Emscripten-style exception handling"),
36  cl::init(false));
37 
38 // Emscripten's asm.js-style setjmp/longjmp handling
40  "enable-emscripten-sjlj",
41  cl::desc("WebAssembly Emscripten-style setjmp/longjmp handling"),
42  cl::init(false));
43 
45  // Register the target.
50 
51  // Register exception handling pass to opt
54 }
55 
56 //===----------------------------------------------------------------------===//
57 // WebAssembly Lowering public interface.
58 //===----------------------------------------------------------------------===//
59 
61  if (!RM.hasValue())
62  return Reloc::PIC_;
63  return *RM;
64 }
65 
66 /// Create an WebAssembly architecture model.
67 ///
69  const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
70  const TargetOptions &Options, Optional<Reloc::Model> RM,
73  TT.isArch64Bit() ? "e-m:e-p:64:64-i64:64-n32:64-S128"
74  : "e-m:e-p:32:32-i64:64-n32:64-S128",
75  TT, CPU, FS, Options, getEffectiveRelocModel(RM),
76  CM ? *CM : CodeModel::Large, OL),
77  TLOF(TT.isOSBinFormatELF() ?
78  static_cast<TargetLoweringObjectFile*>(
80  static_cast<TargetLoweringObjectFile*>(
82  // WebAssembly type-checks instructions, but a noreturn function with a return
83  // type that doesn't match the context will cause a check failure. So we lower
84  // LLVM 'unreachable' to ISD::TRAP and then lower that to WebAssembly's
85  // 'unreachable' instructions which is meant for that case.
86  this->Options.TrapUnreachable = true;
87 
88  // WebAssembly treats each function as an independent unit. Force
89  // -ffunction-sections, effectively, so that we can emit them independently.
90  if (!TT.isOSBinFormatELF()) {
91  this->Options.FunctionSections = true;
92  this->Options.DataSections = true;
93  this->Options.UniqueSectionNames = true;
94  }
95 
96  initAsmInfo();
97 
98  // Note that we don't use setRequiresStructuredCFG(true). It disables
99  // optimizations than we're ok with, and want, such as critical edge
100  // splitting and tail merging.
101 }
102 
104 
105 const WebAssemblySubtarget *
107  Attribute CPUAttr = F.getFnAttribute("target-cpu");
108  Attribute FSAttr = F.getFnAttribute("target-features");
109 
110  std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
111  ? CPUAttr.getValueAsString().str()
112  : TargetCPU;
113  std::string FS = !FSAttr.hasAttribute(Attribute::None)
114  ? FSAttr.getValueAsString().str()
115  : TargetFS;
116 
117  auto &I = SubtargetMap[CPU + FS];
118  if (!I) {
119  // This needs to be done before we create a new subtarget since any
120  // creation will depend on the TM and the code generation flags on the
121  // function that reside in TargetOptions.
123  I = llvm::make_unique<WebAssemblySubtarget>(TargetTriple, CPU, FS, *this);
124  }
125  return I.get();
126 }
127 
128 namespace {
129 /// WebAssembly Code Generator Pass Configuration Options.
130 class WebAssemblyPassConfig final : public TargetPassConfig {
131 public:
132  WebAssemblyPassConfig(WebAssemblyTargetMachine &TM, PassManagerBase &PM)
133  : TargetPassConfig(TM, PM) {}
134 
135  WebAssemblyTargetMachine &getWebAssemblyTargetMachine() const {
136  return getTM<WebAssemblyTargetMachine>();
137  }
138 
139  FunctionPass *createTargetRegisterAllocator(bool) override;
140 
141  void addIRPasses() override;
142  bool addInstSelector() override;
143  void addPostRegAlloc() override;
144  bool addGCPasses() override { return false; }
145  void addPreEmitPass() override;
146 };
147 } // end anonymous namespace
148 
151  return TargetTransformInfo(WebAssemblyTTIImpl(this, F));
152 }
153 
156  return new WebAssemblyPassConfig(*this, PM);
157 }
158 
159 FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(bool) {
160  return nullptr; // No reg alloc
161 }
162 
163 //===----------------------------------------------------------------------===//
164 // The following functions are called from lib/CodeGen/Passes.cpp to modify
165 // the CodeGen pass sequence.
166 //===----------------------------------------------------------------------===//
167 
168 void WebAssemblyPassConfig::addIRPasses() {
169  if (TM->Options.ThreadModel == ThreadModel::Single)
170  // In "single" mode, atomics get lowered to non-atomics.
171  addPass(createLowerAtomicPass());
172  else
173  // Expand some atomic operations. WebAssemblyTargetLowering has hooks which
174  // control specifically what gets lowered.
175  addPass(createAtomicExpandPass());
176 
177  // Lower .llvm.global_dtors into .llvm_global_ctors with __cxa_atexit calls.
179 
180  // Fix function bitcasts, as WebAssembly requires caller and callee signatures
181  // to match.
183 
184  // Optimize "returned" function attributes.
185  if (getOptLevel() != CodeGenOpt::None)
187 
188  // If exception handling is not enabled and setjmp/longjmp handling is
189  // enabled, we lower invokes into calls and delete unreachable landingpad
190  // blocks. Lowering invokes when there is no EH support is done in
191  // TargetPassConfig::addPassesToHandleExceptions, but this runs after this
192  // function and SjLj handling expects all invokes to be lowered before.
193  if (!EnableEmException) {
194  addPass(createLowerInvokePass());
195  // The lower invoke pass may create unreachable code. Remove it in order not
196  // to process dead blocks in setjmp/longjmp handling.
198  }
199 
200  // Handle exceptions and setjmp/longjmp if enabled.
203  EnableEmSjLj));
204 
206 }
207 
208 bool WebAssemblyPassConfig::addInstSelector() {
210  addPass(
211  createWebAssemblyISelDag(getWebAssemblyTargetMachine(), getOptLevel()));
212  // Run the argument-move pass immediately after the ScheduleDAG scheduler
213  // so that we can fix up the ARGUMENT instructions before anything else
214  // sees them in the wrong place.
216  // Set the p2align operands. This information is present during ISel, however
217  // it's inconvenient to collect. Collect it now, and update the immediate
218  // operands.
220  return false;
221 }
222 
223 void WebAssemblyPassConfig::addPostRegAlloc() {
224  // TODO: The following CodeGen passes don't currently support code containing
225  // virtual registers. Consider removing their restrictions and re-enabling
226  // them.
227 
228  // Has no asserts of its own, but was not written to handle virtual regs.
229  disablePass(&ShrinkWrapID);
230 
231  // These functions all require the NoVRegs property.
232  disablePass(&MachineCopyPropagationID);
233  disablePass(&PostRASchedulerID);
234  disablePass(&FuncletLayoutID);
235  disablePass(&StackMapLivenessID);
236  disablePass(&LiveDebugValuesID);
237  disablePass(&PatchableFunctionID);
238 
240 }
241 
242 void WebAssemblyPassConfig::addPreEmitPass() {
244 
245  // Now that we have a prologue and epilogue and all frame indices are
246  // rewritten, eliminate SP and FP. This allows them to be stackified,
247  // colored, and numbered with the rest of the registers.
249 
250  // Rewrite pseudo call_indirect instructions as real instructions.
251  // This needs to run before register stackification, because we change the
252  // order of the arguments.
254 
255  if (getOptLevel() != CodeGenOpt::None) {
256  // LiveIntervals isn't commonly run this late. Re-establish preconditions.
258 
259  // Depend on LiveIntervals and perform some optimizations on it.
261 
262  // Prepare store instructions for register stackifying.
264 
265  // Mark registers as representing wasm's value stack. This is a key
266  // code-compression technique in WebAssembly. We run this pass (and
267  // StoreResults above) very late, so that it sees as much code as possible,
268  // including code emitted by PEI and expanded by late tail duplication.
269  addPass(createWebAssemblyRegStackify());
270 
271  // Run the register coloring pass to reduce the total number of registers.
272  // This runs after stackification so that it doesn't consider registers
273  // that become stackified.
274  addPass(createWebAssemblyRegColoring());
275  }
276 
277  // Eliminate multiple-entry loops. Do this before inserting explicit get_local
278  // and set_local operators because we create a new variable that we want
279  // converted into a local.
281 
282  // Insert explicit get_local and set_local operators.
284 
285  // Sort the blocks of the CFG into topological order, a prerequisite for
286  // BLOCK and LOOP markers.
287  addPass(createWebAssemblyCFGSort());
288 
289  // Insert BLOCK and LOOP markers.
290  addPass(createWebAssemblyCFGStackify());
291 
292  // Lower br_unless into br_if.
294 
295  // Perform the very last peephole optimizations on the code.
296  if (getOptLevel() != CodeGenOpt::None)
297  addPass(createWebAssemblyPeephole());
298 
299  // Create a mapping from LLVM CodeGen virtual registers to wasm registers.
301 }
FunctionPass * createWebAssemblyCallIndirectFixup()
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
ModulePass * createWebAssemblyLowerEmscriptenEHSjLj(bool DoEH, bool DoSjLj)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:228
ModulePass * createWebAssemblyFixFunctionBitcasts()
static cl::opt< bool > EnableEmSjLj("enable-emscripten-sjlj", cl::desc("WebAssembly Emscripten-style setjmp/longjmp handling"), cl::init(false))
FunctionPass * createWebAssemblyArgumentMove()
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
virtual void addIRPasses()
Add common target configurable passes that perform LLVM IR to IR transforms following machine indepen...
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition: Triple.h:588
Triple TargetTriple
Triple string, CPU name, and target feature strings the TargetMachine instance is created with...
Definition: TargetMachine.h:78
This file a TargetTransformInfo::Concept conforming object specific to the WebAssembly target machine...
unsigned DataSections
Emit data into separate sections.
char & FuncletLayoutID
This pass lays out funclets contiguously.
FunctionPass * createWebAssemblyRegNumbering()
FunctionPass * createWebAssemblyOptimizeLiveIntervals()
F(f)
ModulePass * createWebAssemblyLowerGlobalDtors()
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end...
virtual void addPreEmitPass()
This pass may be implemented by targets that want to run passes immediately before machine code is em...
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
This file declares the WebAssembly-specific subclass of TargetLoweringObjectFile. ...
void resetTargetOptions(const Function &F) const
Reset the target options based on the function&#39;s attributes.
FunctionPass * createLowerInvokePass()
Definition: LowerInvoke.cpp:84
No attributes have been set.
Definition: Attributes.h:72
Target-Independent Code Generator Pass Configuration Options.
This file declares the WebAssembly-specific subclass of TargetMachine.
RegisterTargetMachine - Helper template for registering a target machine implementation, for use in the target machine initialization function.
FunctionPass * createWebAssemblyPrepareForLiveIntervals()
unsigned FunctionSections
Emit functions into separate sections.
FunctionPass * createUnreachableBlockEliminationPass()
createUnreachableBlockEliminationPass - The LLVM code generator does not work well with unreachable b...
unsigned UniqueSectionNames
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:406
bool hasAttribute(AttrKind Val) const
Return true if the attribute is present.
Definition: Attributes.cpp:202
CodeGenOpt::Level getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
FunctionPass * createWebAssemblyISelDag(WebAssemblyTargetMachine &TM, CodeGenOpt::Level OptLevel)
This pass converts a legalized DAG into a WebAssembly-specific DAG, ready for instruction scheduling...
static Reloc::Model getEffectiveRelocModel(Optional< Reloc::Model > RM)
This file provides WebAssembly-specific target descriptions.
FunctionPass * createWebAssemblySetP2AlignOperands()
virtual bool addInstSelector()
addInstSelector - This method should install an instruction selector pass, which converts from LLVM c...
FunctionPass * createWebAssemblyLowerBrUnless()
char & LiveDebugValuesID
LiveDebugValues pass.
This class describes a target machine that is implemented with the LLVM target-independent code gener...
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:285
void initializeWebAssemblyLowerEmscriptenEHSjLjPass(PassRegistry &)
char & MachineCopyPropagationID
MachineCopyPropagation - This pass performs copy propagation on machine instructions.
static cl::opt< bool > EnableEmException("enable-emscripten-cxx-exceptions", cl::desc("WebAssembly Emscripten-style exception handling"), cl::init(false))
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
char & PostRASchedulerID
createPostRAScheduler - This pass performs post register allocation scheduling.
FunctionPass * createWebAssemblyStoreResults()
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
PassManagerBase - An abstract interface to allow code to add passes to a pass manager without having ...
char & StackMapLivenessID
StackMapLiveness - This pass analyses the register live-out set of stackmap/patchpoint intrinsics and...
FunctionPass * createWebAssemblyRegStackify()
TargetPassConfig * createPassConfig(PassManagerBase &PM) override
Create a pass configuration object to be used by addPassToEmitX methods for generating a pipeline of ...
FunctionPass * createWebAssemblyExplicitLocals()
FunctionPass * createWebAssemblyCFGStackify()
FunctionPass * createWebAssemblyFixIrreducibleControlFlow()
Pass * createLowerAtomicPass()
Target - Wrapper for Target specific information.
virtual void addPostRegAlloc()
This method may be implemented by targets that want to run passes after register allocation pass pipe...
std::string TargetCPU
Definition: TargetMachine.h:79
FunctionPass * createWebAssemblyPeephole()
char & PatchableFunctionID
This pass implements the "patchable-function" attribute.
bool hasValue() const
Definition: Optional.h:183
StringRef getValueAsString() const
Return the attribute&#39;s value as a string.
Definition: Attributes.cpp:195
TargetTransformInfo getTargetTransformInfo(const Function &F) override
Get a TargetTransformInfo implementation for the target.
FunctionPass * createWebAssemblyReplacePhysRegs()
#define I(x, y, z)
Definition: MD5.cpp:58
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.
void LLVMInitializeWebAssemblyTarget()
std::string TargetFS
Definition: TargetMachine.h:80
FunctionPass * createWebAssemblyRegColoring()
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.h:312
char & ShrinkWrapID
ShrinkWrap pass. Look for the best place to insert save and restore.
Definition: ShrinkWrap.cpp:232
FunctionPass * createWebAssemblyOptimizeReturned()
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
unsigned TrapUnreachable
Emit target-specific trap instruction for &#39;unreachable&#39; IR instructions.
Target & getTheWebAssemblyTarget32()
const WebAssemblySubtarget * getSubtargetImpl(const Function &F) const override
Virtual method implemented by subclasses that returns a reference to that target&#39;s TargetSubtargetInf...
FunctionPass * createAtomicExpandPass()
Target & getTheWebAssemblyTarget64()
FunctionPass * createWebAssemblyCFGSort()