25#include "llvm/IR/IntrinsicsWebAssembly.h"
27#define DEBUG_TYPE "wasm-isel"
33#define GET_GLOBALISEL_PREDICATE_BITSET
34#include "WebAssemblyGenGlobalISel.inc"
35#undef GET_GLOBALISEL_PREDICATE_BITSET
57 selectAddrOperands(
LLT AddrType,
unsigned int ConstOpc,
66#define GET_GLOBALISEL_PREDICATES_DECL
67#include "WebAssemblyGenGlobalISel.inc"
68#undef GET_GLOBALISEL_PREDICATES_DECL
70#define GET_GLOBALISEL_TEMPORARIES_DECL
71#include "WebAssemblyGenGlobalISel.inc"
72#undef GET_GLOBALISEL_TEMPORARIES_DECL
77#define GET_GLOBALISEL_IMPL
78#include "WebAssemblyGenGlobalISel.inc"
79#undef GET_GLOBALISEL_IMPL
81WebAssemblyInstructionSelector::WebAssemblyInstructionSelector(
84 : TM(TM), STI(STI),
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()),
88#include
"WebAssemblyGenGlobalISel.inc"
91#include
"WebAssemblyGenGlobalISel.inc"
97WebAssemblyInstructionSelector::selectAddrOperands(
LLT AddrType,
98 unsigned int ConstOpc,
101 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
102 [=](MachineInstrBuilder &MIB) { MIB.addReg(Root.
getReg()); },
106InstructionSelector::ComplexRendererFns
107WebAssemblyInstructionSelector::selectAddrOperands32(
108 MachineOperand &Root)
const {
109 return selectAddrOperands(
LLT::integer(32), WebAssembly::CONST_I32, Root);
112InstructionSelector::ComplexRendererFns
113WebAssemblyInstructionSelector::selectAddrOperands64(
114 MachineOperand &Root)
const {
115 return selectAddrOperands(
LLT::integer(64), WebAssembly::CONST_I64, Root);
118bool WebAssemblyInstructionSelector::selectCopy(
119 MachineInstr &
I, MachineRegisterInfo &MRI)
const {
120 Register DstReg =
I.getOperand(0).getReg();
121 Register SrcReg =
I.getOperand(1).getReg();
124 TRI.getConstrainedRegClassForReg(DstReg, MRI);
129 TRI.getConstrainedRegClassForReg(SrcReg, MRI);
138 if (DstRC != SrcRC) {
141 "classes not currently supported");
143 if (DstRC == &WebAssembly::I32RegClass &&
144 SrcRC == &WebAssembly::F32RegClass) {
145 I.setDesc(
TII.get(WebAssembly::I32_REINTERPRET_F32));
148 if (DstRC == &WebAssembly::F32RegClass &&
149 SrcRC == &WebAssembly::I32RegClass) {
150 I.setDesc(
TII.get(WebAssembly::F32_REINTERPRET_I32));
153 if (DstRC == &WebAssembly::I64RegClass &&
154 SrcRC == &WebAssembly::F64RegClass) {
155 I.setDesc(
TII.get(WebAssembly::I64_REINTERPRET_F64));
158 if (DstRC == &WebAssembly::F64RegClass &&
159 SrcRC == &WebAssembly::I64RegClass) {
160 I.setDesc(
TII.get(WebAssembly::F64_REINTERPRET_I64));
170bool WebAssemblyInstructionSelector::select(MachineInstr &
I) {
176 if (!
I.isPreISelOpcode()) {
182 if (selectImpl(
I, *CoverageInfo))
185 using namespace TargetOpcode;
187 switch (
I.getOpcode()) {
188 case G_IMPLICIT_DEF: {
189 const Register DefReg =
I.getOperand(0).getReg();
192 TRI.getConstrainedRegClassForReg(DefReg, MRI);
197 I.setDesc(
TII.get(TargetOpcode::IMPLICIT_DEF));
204 TII.get(PtrIsI64 ? WebAssembly::COPY_I64 : WebAssembly::COPY_I32));
212 TII.get(PtrIsI64 ? WebAssembly::COPY_I64 : WebAssembly::COPY_I32));
219 I.setDesc(
TII.get(PtrIsI64 ? WebAssembly::AND_I64 : WebAssembly::AND_I32));
223 case G_GLOBAL_VALUE: {
224 assert(
I.getOperand(1).getTargetFlags() == 0 &&
225 "Unexpected target flags on generic G_GLOBAL_VALUE instruction");
228 const llvm::GlobalValue *GV =
I.getOperand(1).getGlobal();
229 LLT PtrTy = MRI.
getType(
I.getOperand(0).getReg());
234 const char *BaseName;
242 MachineIRBuilder
B(
I);
245 PtrIsI64 ? &WebAssembly::I64RegClass : &WebAssembly::I32RegClass);
248 PtrIsI64 ? &WebAssembly::I64RegClass : &WebAssembly::I32RegClass);
250 B.buildInstr(PtrIsI64 ? WebAssembly::GLOBAL_GET_I64
251 : WebAssembly::GLOBAL_GET_I32)
253 .addExternalSymbol(BaseName);
255 B.buildInstr(PtrIsI64 ? WebAssembly::CONST_I64 : WebAssembly::CONST_I32)
257 .addGlobalAddress(GV,
I.getOperand(1).getOffset(), OperandFlags);
260 B.buildInstr(PtrIsI64 ? WebAssembly::ADD_I64 : WebAssembly::ADD_I32)
261 .addDef(
I.getOperand(0).getReg())
273 PtrIsI64 ? WebAssembly::CONST_I64 : WebAssembly::CONST_I32;
277 PtrIsI64 ? WebAssembly::GLOBAL_GET_I64 : WebAssembly::GLOBAL_GET_I32;
280 I.setDesc(
TII.get(NewOpc));
281 I.getOperand(1).setTargetFlags(OperandFlags);
298 return new WebAssemblyInstructionSelector(TM, Subtarget, RBI);
#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)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
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.
std::optional< SmallVector< std::function< void(MachineInstrBuilder &)>, 4 > > ComplexRendererFns
Type * getValueType() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
static LLT integer(unsigned SizeInBits)
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const char * createExternalSymbolName(StringRef Name)
Allocate a string and populate it with the given external symbol name.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
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.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
bool isPositionIndependent() const
bool shouldAssumeDSOLocal(const GlobalValue *GV) const
bool isFunctionTy() const
True if this is an instance of FunctionType.
This class provides the information for the target register banks.
const WebAssemblyTargetLowering * getTargetLowering() const override
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
OperandFlags
These are flags set on operands, but should be considered private, all access should go through the M...
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
InstructionSelector * createWebAssemblyInstructionSelector(const WebAssemblyTargetMachine &TM, const WebAssemblySubtarget &Subtarget, const WebAssemblyRegisterBankInfo &RBI)
MCRegisterClass TargetRegisterClass