WebAssemblyTargetMachine.cpp revision 285163
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
15#include "WebAssembly.h"
16#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
17#include "WebAssemblyTargetMachine.h"
18#include "WebAssemblyTargetObjectFile.h"
19#include "WebAssemblyTargetTransformInfo.h"
20#include "llvm/CodeGen/MachineFunctionPass.h"
21#include "llvm/CodeGen/Passes.h"
22#include "llvm/CodeGen/RegAllocRegistry.h"
23#include "llvm/IR/Function.h"
24#include "llvm/Support/CommandLine.h"
25#include "llvm/Support/TargetRegistry.h"
26#include "llvm/Target/TargetOptions.h"
27#include "llvm/Transforms/Scalar.h"
28using namespace llvm;
29
30#define DEBUG_TYPE "wasm"
31
32extern "C" void LLVMInitializeWebAssemblyTarget() {
33  // Register the target.
34  RegisterTargetMachine<WebAssemblyTargetMachine> X(TheWebAssemblyTarget32);
35  RegisterTargetMachine<WebAssemblyTargetMachine> Y(TheWebAssemblyTarget64);
36}
37
38//===----------------------------------------------------------------------===//
39// WebAssembly Lowering public interface.
40//===----------------------------------------------------------------------===//
41
42/// Create an WebAssembly architecture model.
43///
44WebAssemblyTargetMachine::WebAssemblyTargetMachine(
45    const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
46    const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM,
47    CodeGenOpt::Level OL)
48    : LLVMTargetMachine(T, TT.isArch64Bit()
49                               ? "e-p:64:64-i64:64-v128:8:128-n32:64-S128"
50                               : "e-p:32:32-i64:64-v128:8:128-n32:64-S128",
51                        TT, CPU, FS, Options, RM, CM, OL),
52      TLOF(make_unique<WebAssemblyTargetObjectFile>()) {
53  initAsmInfo();
54
55  // We need a reducible CFG, so disable some optimizations which tend to
56  // introduce irreducibility.
57  setRequiresStructuredCFG(true);
58}
59
60WebAssemblyTargetMachine::~WebAssemblyTargetMachine() {}
61
62const WebAssemblySubtarget *
63WebAssemblyTargetMachine::getSubtargetImpl(const Function &F) const {
64  Attribute CPUAttr = F.getFnAttribute("target-cpu");
65  Attribute FSAttr = F.getFnAttribute("target-features");
66
67  std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
68                        ? CPUAttr.getValueAsString().str()
69                        : TargetCPU;
70  std::string FS = !FSAttr.hasAttribute(Attribute::None)
71                       ? FSAttr.getValueAsString().str()
72                       : TargetFS;
73
74  auto &I = SubtargetMap[CPU + FS];
75  if (!I) {
76    // This needs to be done before we create a new subtarget since any
77    // creation will depend on the TM and the code generation flags on the
78    // function that reside in TargetOptions.
79    resetTargetOptions(F);
80    I = make_unique<WebAssemblySubtarget>(TargetTriple, CPU, FS, *this);
81  }
82  return I.get();
83}
84
85namespace {
86/// WebAssembly Code Generator Pass Configuration Options.
87class WebAssemblyPassConfig final : public TargetPassConfig {
88public:
89  WebAssemblyPassConfig(WebAssemblyTargetMachine *TM, PassManagerBase &PM)
90      : TargetPassConfig(TM, PM) {}
91
92  WebAssemblyTargetMachine &getWebAssemblyTargetMachine() const {
93    return getTM<WebAssemblyTargetMachine>();
94  }
95
96  FunctionPass *createTargetRegisterAllocator(bool) override;
97  void addFastRegAlloc(FunctionPass *RegAllocPass) override;
98  void addOptimizedRegAlloc(FunctionPass *RegAllocPass) override;
99
100  void addIRPasses() override;
101  bool addPreISel() override;
102  bool addInstSelector() override;
103  bool addILPOpts() override;
104  void addPreRegAlloc() override;
105  void addRegAllocPasses(bool Optimized);
106  void addPostRegAlloc() override;
107  void addPreSched2() override;
108  void addPreEmitPass() override;
109};
110} // end anonymous namespace
111
112TargetIRAnalysis WebAssemblyTargetMachine::getTargetIRAnalysis() {
113  return TargetIRAnalysis([this](Function &F) {
114    return TargetTransformInfo(WebAssemblyTTIImpl(this, F));
115  });
116}
117
118TargetPassConfig *
119WebAssemblyTargetMachine::createPassConfig(PassManagerBase &PM) {
120  return new WebAssemblyPassConfig(this, PM);
121}
122
123FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(bool) {
124  return nullptr; // No reg alloc
125}
126
127void WebAssemblyPassConfig::addFastRegAlloc(FunctionPass *RegAllocPass) {
128  assert(!RegAllocPass && "WebAssembly uses no regalloc!");
129  addRegAllocPasses(false);
130}
131
132void WebAssemblyPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) {
133  assert(!RegAllocPass && "WebAssembly uses no regalloc!");
134  addRegAllocPasses(true);
135}
136
137//===----------------------------------------------------------------------===//
138// The following functions are called from lib/CodeGen/Passes.cpp to modify
139// the CodeGen pass sequence.
140//===----------------------------------------------------------------------===//
141
142void WebAssemblyPassConfig::addIRPasses() {
143  // FIXME: the default for this option is currently POSIX, whereas
144  // WebAssembly's MVP should default to Single.
145  if (TM->Options.ThreadModel == ThreadModel::Single)
146    addPass(createLowerAtomicPass());
147  else
148    // Expand some atomic operations. WebAssemblyTargetLowering has hooks which
149    // control specifically what gets lowered.
150    addPass(createAtomicExpandPass(TM));
151
152  TargetPassConfig::addIRPasses();
153}
154
155bool WebAssemblyPassConfig::addPreISel() { return false; }
156
157bool WebAssemblyPassConfig::addInstSelector() {
158  addPass(
159      createWebAssemblyISelDag(getWebAssemblyTargetMachine(), getOptLevel()));
160  return false;
161}
162
163bool WebAssemblyPassConfig::addILPOpts() { return true; }
164
165void WebAssemblyPassConfig::addPreRegAlloc() {}
166
167void WebAssemblyPassConfig::addRegAllocPasses(bool Optimized) {}
168
169void WebAssemblyPassConfig::addPostRegAlloc() {}
170
171void WebAssemblyPassConfig::addPreSched2() {}
172
173void WebAssemblyPassConfig::addPreEmitPass() {}
174