LLVM 23.0.0git
WebAssemblyInstructionSelector.cpp
Go to the documentation of this file.
1//===- WebAssemblyInstructionSelector.cpp ------------------------*- C++ -*-==//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements the targeting of the InstructionSelector class for
10/// WebAssembly.
11/// \todo This should be generated by TableGen.
12//===----------------------------------------------------------------------===//
13
25#include "llvm/IR/IntrinsicsWebAssembly.h"
26
27#define DEBUG_TYPE "wasm-isel"
28
29using namespace llvm;
30
31namespace {
32
33#define GET_GLOBALISEL_PREDICATE_BITSET
34#include "WebAssemblyGenGlobalISel.inc"
35#undef GET_GLOBALISEL_PREDICATE_BITSET
36
37class WebAssemblyInstructionSelector : public InstructionSelector {
38public:
39 WebAssemblyInstructionSelector(const WebAssemblyTargetMachine &TM,
40 const WebAssemblySubtarget &STI,
42
43 bool select(MachineInstr &I) override;
44
45 static const char *getName() { return DEBUG_TYPE; }
46
47private:
48 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
50
52 // const WebAssemblySubtarget &STI;
56
57#define GET_GLOBALISEL_PREDICATES_DECL
58#include "WebAssemblyGenGlobalISel.inc"
59#undef GET_GLOBALISEL_PREDICATES_DECL
60
61#define GET_GLOBALISEL_TEMPORARIES_DECL
62#include "WebAssemblyGenGlobalISel.inc"
63#undef GET_GLOBALISEL_TEMPORARIES_DECL
64};
65
66} // end anonymous namespace
67
68#define GET_GLOBALISEL_IMPL
69#include "WebAssemblyGenGlobalISel.inc"
70#undef GET_GLOBALISEL_IMPL
71
72WebAssemblyInstructionSelector::WebAssemblyInstructionSelector(
75 : TM(TM), /*STI(STI),*/ TII(*STI.getInstrInfo()),
76 TRI(*STI.getRegisterInfo()), RBI(RBI),
77
79#include "WebAssemblyGenGlobalISel.inc"
82#include "WebAssemblyGenGlobalISel.inc"
84{
85}
86
87bool WebAssemblyInstructionSelector::selectCopy(
88 MachineInstr &I, MachineRegisterInfo &MRI) const {
89 const TargetRegisterClass *DstRC =
90 TRI.getConstrainedRegClassForOperand(I.getOperand(0), MRI);
91 if (!DstRC)
92 return false;
93
94 const TargetRegisterClass *SrcRC =
95 TRI.getConstrainedRegClassForOperand(I.getOperand(1), MRI);
96 if (!SrcRC)
97 return false;
98
99 Register DstReg = I.getOperand(0).getReg();
100 Register SrcReg = I.getOperand(1).getReg();
101
102 if (DstReg.isVirtual())
103 RBI.constrainGenericRegister(DstReg, *DstRC, MRI);
104 if (SrcReg.isVirtual())
105 RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI);
106
107 if (DstRC != SrcRC) {
108 if (DstReg.isPhysical() || SrcReg.isPhysical())
109 llvm_unreachable("COPY to/from SP[32/64] or FP[32/64] with mismatching "
110 "classes not currently supported");
111
112 if (DstRC == &WebAssembly::I32RegClass &&
113 SrcRC == &WebAssembly::F32RegClass) {
114 I.setDesc(TII.get(WebAssembly::I32_REINTERPRET_F32));
115 return true;
116 }
117 if (DstRC == &WebAssembly::F32RegClass &&
118 SrcRC == &WebAssembly::I32RegClass) {
119 I.setDesc(TII.get(WebAssembly::F32_REINTERPRET_I32));
120 return true;
121 }
122 if (DstRC == &WebAssembly::I64RegClass &&
123 SrcRC == &WebAssembly::F64RegClass) {
124 I.setDesc(TII.get(WebAssembly::I64_REINTERPRET_F64));
125 return true;
126 }
127 if (DstRC == &WebAssembly::F64RegClass &&
128 SrcRC == &WebAssembly::I64RegClass) {
129 I.setDesc(TII.get(WebAssembly::F64_REINTERPRET_I64));
130 return true;
131 }
132
133 llvm_unreachable("COPY between unsupported reg classes.");
134 }
135
136 return true;
137}
138
139bool WebAssemblyInstructionSelector::select(MachineInstr &I) {
140 MachineBasicBlock &MBB = *I.getParent();
141 MachineFunction &MF = *MBB.getParent();
142 MachineRegisterInfo &MRI = MF.getRegInfo();
143
144 if (!I.isPreISelOpcode()) {
145 if (I.isCopy())
146 return selectCopy(I, MRI);
147 return true;
148 }
149
150 if (selectImpl(I, *CoverageInfo))
151 return true;
152
153 using namespace TargetOpcode;
154
155 switch (I.getOpcode()) {
156 case G_IMPLICIT_DEF: {
157 const Register DefReg = I.getOperand(0).getReg();
158
159 const TargetRegisterClass *DefRC =
160 TRI.getConstrainedRegClassForOperand(I.getOperand(0), MRI);
161
162 if (!DefRC)
163 return false;
164
165 I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));
166 return RBI.constrainGenericRegister(DefReg, *DefRC, MRI) != nullptr;
167 }
168 default:
169 break;
170 }
171
172 return false;
173}
174
175namespace llvm {
176InstructionSelector *
178 const WebAssemblySubtarget &Subtarget,
179 const WebAssemblyRegisterBankInfo &RBI) {
180 return new WebAssemblyInstructionSelector(TM, Subtarget, RBI);
181}
182} // namespace llvm
#define GET_GLOBALISEL_PREDICATES_INIT
#define GET_GLOBALISEL_TEMPORARIES_INIT
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
MachineBasicBlock & MBB
#define DEBUG_TYPE
const HexagonInstrInfo * TII
#define I(x, y, z)
Definition MD5.cpp:57
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
static StringRef getName(Value *V)
This file describes how to lower LLVM code to machine code.
This file provides WebAssembly-specific target descriptions.
This file declares the targeting of the RegisterBankInfo class for WebAssembly.
This file contains the WebAssembly implementation of the WebAssemblyRegisterInfo class.
This file declares the WebAssembly-specific subclass of TargetSubtarget.
This file declares the WebAssembly-specific subclass of TargetMachine.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static const TargetRegisterClass * constrainGenericRegister(Register Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI)
Constrain the (possibly generic) virtual register Reg to RC.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:79
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:83
This class provides the information for the target register banks.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
InstructionSelector * createWebAssemblyInstructionSelector(const WebAssemblyTargetMachine &TM, const WebAssemblySubtarget &Subtarget, const WebAssemblyRegisterBankInfo &RBI)