blob: 0f3ac94994b28de40018702bb9bab91274e29d03 [file] [log] [blame]
Dan Gohman10e730a2015-06-29 23:51:55 +00001//===- 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"
JF Bastien03855df2015-07-01 23:41:25 +000027#include "llvm/Transforms/Scalar.h"
Dan Gohman10e730a2015-06-29 23:51:55 +000028using namespace llvm;
29
30#define DEBUG_TYPE "wasm"
31
32extern "C" void LLVMInitializeWebAssemblyTarget() {
33 // Register the target.
Dan Gohmand82494b2015-07-01 21:42:34 +000034 RegisterTargetMachine<WebAssemblyTargetMachine> X(TheWebAssemblyTarget32);
35 RegisterTargetMachine<WebAssemblyTargetMachine> Y(TheWebAssemblyTarget64);
Dan Gohman10e730a2015-06-29 23:51:55 +000036}
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);
Rafael Espindola3adc7ce2015-08-11 18:11:17 +000080 I = llvm::make_unique<WebAssemblySubtarget>(TargetTriple, CPU, FS, *this);
Dan Gohman10e730a2015-06-29 23:51:55 +000081 }
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() {
JF Bastien03855df2015-07-01 23:41:25 +0000143 // 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));
Dan Gohman10e730a2015-06-29 23:51:55 +0000151
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
JF Bastien600aee92015-07-31 17:53:38 +0000169void WebAssemblyPassConfig::addPostRegAlloc() {
170 // FIXME: the following passes dislike virtual registers. Disable them for now
171 // so that basic tests can pass. Future patches will remedy this.
172 //
173 // Fails with: Regalloc must assign all vregs.
174 disablePass(&PrologEpilogCodeInserterID);
175 // Fails with: should be run after register allocation.
176 disablePass(&MachineCopyPropagationID);
177}
Dan Gohman10e730a2015-06-29 23:51:55 +0000178
179void WebAssemblyPassConfig::addPreSched2() {}
180
181void WebAssemblyPassConfig::addPreEmitPass() {}