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