27#include "llvm/IR/IntrinsicsWebAssembly.h"
29#define DEBUG_TYPE "wasm-isel"
35#define GET_GLOBALISEL_PREDICATE_BITSET
36#include "WebAssemblyGenGlobalISel.inc"
37#undef GET_GLOBALISEL_PREDICATE_BITSET
59 selectAddrOperands(
LLT AddrType,
unsigned int ConstOpc,
68#define GET_GLOBALISEL_PREDICATES_DECL
69#include "WebAssemblyGenGlobalISel.inc"
70#undef GET_GLOBALISEL_PREDICATES_DECL
72#define GET_GLOBALISEL_TEMPORARIES_DECL
73#include "WebAssemblyGenGlobalISel.inc"
74#undef GET_GLOBALISEL_TEMPORARIES_DECL
79#define GET_GLOBALISEL_IMPL
80#include "WebAssemblyGenGlobalISel.inc"
81#undef GET_GLOBALISEL_IMPL
83WebAssemblyInstructionSelector::WebAssemblyInstructionSelector(
86 : TM(TM), STI(STI),
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()),
90#include
"WebAssemblyGenGlobalISel.inc"
93#include
"WebAssemblyGenGlobalISel.inc"
99WebAssemblyInstructionSelector::selectAddrOperands(
LLT AddrType,
100 unsigned int ConstOpc,
103 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
104 [=](MachineInstrBuilder &MIB) { MIB.addReg(Root.
getReg()); },
108InstructionSelector::ComplexRendererFns
109WebAssemblyInstructionSelector::selectAddrOperands32(
110 MachineOperand &Root)
const {
111 return selectAddrOperands(
LLT::integer(32), WebAssembly::CONST_I32, Root);
114InstructionSelector::ComplexRendererFns
115WebAssemblyInstructionSelector::selectAddrOperands64(
116 MachineOperand &Root)
const {
117 return selectAddrOperands(
LLT::integer(64), WebAssembly::CONST_I64, Root);
120bool WebAssemblyInstructionSelector::selectCopy(
121 MachineInstr &
I, MachineRegisterInfo &MRI)
const {
122 Register DstReg =
I.getOperand(0).getReg();
123 Register SrcReg =
I.getOperand(1).getReg();
126 TRI.getConstrainedRegClassForReg(DstReg, MRI);
131 TRI.getConstrainedRegClassForReg(SrcReg, MRI);
140 if (DstRC != SrcRC) {
143 "classes not currently supported");
145 if (DstRC == &WebAssembly::I32RegClass &&
146 SrcRC == &WebAssembly::F32RegClass) {
147 I.setDesc(
TII.get(WebAssembly::I32_REINTERPRET_F32));
150 if (DstRC == &WebAssembly::F32RegClass &&
151 SrcRC == &WebAssembly::I32RegClass) {
152 I.setDesc(
TII.get(WebAssembly::F32_REINTERPRET_I32));
155 if (DstRC == &WebAssembly::I64RegClass &&
156 SrcRC == &WebAssembly::F64RegClass) {
157 I.setDesc(
TII.get(WebAssembly::I64_REINTERPRET_F64));
160 if (DstRC == &WebAssembly::F64RegClass &&
161 SrcRC == &WebAssembly::I64RegClass) {
162 I.setDesc(
TII.get(WebAssembly::F64_REINTERPRET_I64));
172bool WebAssemblyInstructionSelector::select(MachineInstr &
I) {
178 if (!
I.isPreISelOpcode()) {
184 if (selectImpl(
I, *CoverageInfo))
187 using namespace TargetOpcode;
189 switch (
I.getOpcode()) {
190 case G_IMPLICIT_DEF: {
191 const Register DefReg =
I.getOperand(0).getReg();
194 TRI.getConstrainedRegClassForReg(DefReg, MRI);
199 I.setDesc(
TII.get(TargetOpcode::IMPLICIT_DEF));
206 TII.get(PtrIsI64 ? WebAssembly::COPY_I64 : WebAssembly::COPY_I32));
214 TII.get(PtrIsI64 ? WebAssembly::COPY_I64 : WebAssembly::COPY_I32));
221 I.setDesc(
TII.get(PtrIsI64 ? WebAssembly::AND_I64 : WebAssembly::AND_I32));
225 case G_GLOBAL_VALUE: {
226 assert(
I.getOperand(1).getTargetFlags() == 0 &&
227 "Unexpected target flags on generic G_GLOBAL_VALUE instruction");
230 const llvm::GlobalValue *GV =
I.getOperand(1).getGlobal();
231 LLT PtrTy = MRI.
getType(
I.getOperand(0).getReg());
236 const char *BaseName;
244 MachineIRBuilder
B(
I);
247 PtrIsI64 ? &WebAssembly::I64RegClass : &WebAssembly::I32RegClass);
250 PtrIsI64 ? &WebAssembly::I64RegClass : &WebAssembly::I32RegClass);
252 B.buildInstr(PtrIsI64 ? WebAssembly::GLOBAL_GET_I64
253 : WebAssembly::GLOBAL_GET_I32)
255 .addExternalSymbol(BaseName);
257 B.buildInstr(PtrIsI64 ? WebAssembly::CONST_I64 : WebAssembly::CONST_I32)
259 .addGlobalAddress(GV,
I.getOperand(1).getOffset(), OperandFlags);
262 B.buildInstr(PtrIsI64 ? WebAssembly::ADD_I64 : WebAssembly::ADD_I32)
263 .addDef(
I.getOperand(0).getReg())
275 PtrIsI64 ? WebAssembly::CONST_I64 : WebAssembly::CONST_I32;
279 PtrIsI64 ? WebAssembly::GLOBAL_GET_I64 : WebAssembly::GLOBAL_GET_I32;
282 I.setDesc(
TII.get(NewOpc));
283 I.getOperand(1).setTargetFlags(OperandFlags);
300 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.
This file contains the declaration of the WebAssembly-specific type parsing utility functions.
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