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