blob: 18e2e5057db55a9556fc70f2757fc7c6a159815f [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()
Dan Gohmandde8dce2015-08-19 20:30:20 +000049 ? "e-p:64:64-i64:64-n32:64-S128"
50 : "e-p:32:32-i64:64-n32:64-S128",
Dan Gohman10e730a2015-06-29 23:51:55 +000051 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;
Dan Gohman10e730a2015-06-29 23:51:55 +000097
98 void addIRPasses() override;
99 bool addPreISel() override;
100 bool addInstSelector() override;
101 bool addILPOpts() override;
102 void addPreRegAlloc() override;
Dan Gohman10e730a2015-06-29 23:51:55 +0000103 void addPostRegAlloc() override;
104 void addPreSched2() override;
105 void addPreEmitPass() override;
106};
107} // end anonymous namespace
108
109TargetIRAnalysis WebAssemblyTargetMachine::getTargetIRAnalysis() {
Hans Wennborg9099b5e62015-09-16 23:59:57 +0000110 return TargetIRAnalysis([this](const Function &F) {
Dan Gohman10e730a2015-06-29 23:51:55 +0000111 return TargetTransformInfo(WebAssemblyTTIImpl(this, F));
112 });
113}
114
115TargetPassConfig *
116WebAssemblyTargetMachine::createPassConfig(PassManagerBase &PM) {
117 return new WebAssemblyPassConfig(this, PM);
118}
119
120FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(bool) {
121 return nullptr; // No reg alloc
122}
123
Dan Gohman10e730a2015-06-29 23:51:55 +0000124//===----------------------------------------------------------------------===//
125// The following functions are called from lib/CodeGen/Passes.cpp to modify
126// the CodeGen pass sequence.
127//===----------------------------------------------------------------------===//
128
129void WebAssemblyPassConfig::addIRPasses() {
JF Bastien03855df2015-07-01 23:41:25 +0000130 // FIXME: the default for this option is currently POSIX, whereas
131 // WebAssembly's MVP should default to Single.
132 if (TM->Options.ThreadModel == ThreadModel::Single)
133 addPass(createLowerAtomicPass());
134 else
135 // Expand some atomic operations. WebAssemblyTargetLowering has hooks which
136 // control specifically what gets lowered.
137 addPass(createAtomicExpandPass(TM));
Dan Gohman10e730a2015-06-29 23:51:55 +0000138
139 TargetPassConfig::addIRPasses();
140}
141
142bool WebAssemblyPassConfig::addPreISel() { return false; }
143
144bool WebAssemblyPassConfig::addInstSelector() {
145 addPass(
146 createWebAssemblyISelDag(getWebAssemblyTargetMachine(), getOptLevel()));
147 return false;
148}
149
150bool WebAssemblyPassConfig::addILPOpts() { return true; }
151
152void WebAssemblyPassConfig::addPreRegAlloc() {}
153
JF Bastien600aee92015-07-31 17:53:38 +0000154void WebAssemblyPassConfig::addPostRegAlloc() {
155 // FIXME: the following passes dislike virtual registers. Disable them for now
156 // so that basic tests can pass. Future patches will remedy this.
157 //
158 // Fails with: Regalloc must assign all vregs.
159 disablePass(&PrologEpilogCodeInserterID);
160 // Fails with: should be run after register allocation.
161 disablePass(&MachineCopyPropagationID);
Dan Gohman950a13c2015-09-16 16:51:30 +0000162
163 // TODO: Until we get ReverseBranchCondition support, MachineBlockPlacement
164 // can create ugly-looking control flow.
165 disablePass(&MachineBlockPlacementID);
JF Bastien600aee92015-07-31 17:53:38 +0000166}
Dan Gohman10e730a2015-06-29 23:51:55 +0000167
168void WebAssemblyPassConfig::addPreSched2() {}
169
Dan Gohman950a13c2015-09-16 16:51:30 +0000170void WebAssemblyPassConfig::addPreEmitPass() {
171 addPass(createWebAssemblyCFGStackify());
172}