LLVM  6.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 
150  return TargetIRAnalysis([this](const Function &F) {
151  return TargetTransformInfo(WebAssemblyTTIImpl(this, F));
152  });
153 }
154 
157  return new WebAssemblyPassConfig(*this, PM);
158 }
159 
160 FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(bool) {
161  return nullptr; // No reg alloc
162 }
163 
164 //===----------------------------------------------------------------------===//
165 // The following functions are called from lib/CodeGen/Passes.cpp to modify
166 // the CodeGen pass sequence.
167 //===----------------------------------------------------------------------===//
168 
169 void WebAssemblyPassConfig::addIRPasses() {
170  if (TM->Options.ThreadModel == ThreadModel::Single)
171  // In "single" mode, atomics get lowered to non-atomics.
172  addPass(createLowerAtomicPass());
173  else
174  // Expand some atomic operations. WebAssemblyTargetLowering has hooks which
175  // control specifically what gets lowered.
176  addPass(createAtomicExpandPass());
177 
178  // Fix function bitcasts, as WebAssembly requires caller and callee signatures
179  // to match.
181 
182  // Optimize "returned" function attributes.
183  if (getOptLevel() != CodeGenOpt::None)
185 
186  // If exception handling is not enabled and setjmp/longjmp handling is
187  // enabled, we lower invokes into calls and delete unreachable landingpad
188  // blocks. Lowering invokes when there is no EH support is done in
189  // TargetPassConfig::addPassesToHandleExceptions, but this runs after this
190  // function and SjLj handling expects all invokes to be lowered before.
191  if (!EnableEmException) {
192  addPass(createLowerInvokePass());
193  // The lower invoke pass may create unreachable code. Remove it in order not
194  // to process dead blocks in setjmp/longjmp handling.
196  }
197 
198  // Handle exceptions and setjmp/longjmp if enabled.
201  EnableEmSjLj));
202 
204 }
205 
206 bool WebAssemblyPassConfig::addInstSelector() {
208  addPass(
209  createWebAssemblyISelDag(getWebAssemblyTargetMachine(), getOptLevel()));
210  // Run the argument-move pass immediately after the ScheduleDAG scheduler
211  // so that we can fix up the ARGUMENT instructions before anything else
212  // sees them in the wrong place.
214  // Set the p2align operands. This information is present during ISel, however
215  // it's inconvenient to collect. Collect it now, and update the immediate
216  // operands.
218  return false;
219 }
220 
221 void WebAssemblyPassConfig::addPostRegAlloc() {
222  // TODO: The following CodeGen passes don't currently support code containing
223  // virtual registers. Consider removing their restrictions and re-enabling
224  // them.
225 
226  // Has no asserts of its own, but was not written to handle virtual regs.
227  disablePass(&ShrinkWrapID);
228 
229  // These functions all require the NoVRegs property.
230  disablePass(&MachineCopyPropagationID);
231  disablePass(&PostRASchedulerID);
232  disablePass(&FuncletLayoutID);
233  disablePass(&StackMapLivenessID);
234  disablePass(&LiveDebugValuesID);
235  disablePass(&PatchableFunctionID);
236 
238 }
239 
240 void WebAssemblyPassConfig::addPreEmitPass() {
242 
243  // Now that we have a prologue and epilogue and all frame indices are
244  // rewritten, eliminate SP and FP. This allows them to be stackified,
245  // colored, and numbered with the rest of the registers.
247 
248  // Rewrite pseudo call_indirect instructions as real instructions.
249  // This needs to run before register stackification, because we change the
250  // order of the arguments.
252 
253  if (getOptLevel() != CodeGenOpt::None) {
254  // LiveIntervals isn't commonly run this late. Re-establish preconditions.
256 
257  // Depend on LiveIntervals and perform some optimizations on it.
259 
260  // Prepare store instructions for register stackifying.
262 
263  // Mark registers as representing wasm's value stack. This is a key
264  // code-compression technique in WebAssembly. We run this pass (and
265  // StoreResults above) very late, so that it sees as much code as possible,
266  // including code emitted by PEI and expanded by late tail duplication.
267  addPass(createWebAssemblyRegStackify());
268 
269  // Run the register coloring pass to reduce the total number of registers.
270  // This runs after stackification so that it doesn't consider registers
271  // that become stackified.
272  addPass(createWebAssemblyRegColoring());
273  }
274 
275  // Eliminate multiple-entry loops. Do this before inserting explicit get_local
276  // and set_local operators because we create a new variable that we want
277  // converted into a local.
279 
280  // Insert explicit get_local and set_local operators.
282 
283  // Sort the blocks of the CFG into topological order, a prerequisite for
284  // BLOCK and LOOP markers.
285  addPass(createWebAssemblyCFGSort());
286 
287  // Insert BLOCK and LOOP markers.
288  addPass(createWebAssemblyCFGStackify());
289 
290  // Lower br_unless into br_if.
292 
293  // Perform the very last peephole optimizations on the code.
294  if (getOptLevel() != CodeGenOpt::None)
295  addPass(createWebAssemblyPeephole());
296 
297  // Create a mapping from LLVM CodeGen virtual registers to wasm registers.
299 }
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:76
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()
Analysis pass providing the TargetTransformInfo.
FunctionPass * createWebAssemblyOptimizeLiveIntervals()
TargetIRAnalysis getTargetIRAnalysis() override
Get the TargetIRAnalysis for this target.
F(f)
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:77
FunctionPass * createWebAssemblyPeephole()
char & PatchableFunctionID
This pass implements the "patchable-function" attribute.
bool hasValue() const
Definition: Optional.h:137
StringRef getValueAsString() const
Return the attribute&#39;s value as a string.
Definition: Attributes.cpp:195
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:78
FunctionPass * createWebAssemblyRegColoring()
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.h:270
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()