Go to the documentation of this file.
32 #define DEBUG_TYPE "wasm-explicit-locals"
37 return "WebAssembly Explicit Locals";
56 "Convert registers to WebAssembly locals",
false,
false)
59 return new WebAssemblyExplicitLocals();
67 dbgs() <<
"Allocating local " << Local <<
"for VReg "
79 auto P = Reg2Local.
insert(std::make_pair(
Reg, CurLocal));
84 return P.first->second;
89 if (RC == &WebAssembly::I32RegClass)
90 return WebAssembly::DROP_I32;
91 if (RC == &WebAssembly::I64RegClass)
92 return WebAssembly::DROP_I64;
93 if (RC == &WebAssembly::F32RegClass)
94 return WebAssembly::DROP_F32;
95 if (RC == &WebAssembly::F64RegClass)
96 return WebAssembly::DROP_F64;
97 if (RC == &WebAssembly::V128RegClass)
98 return WebAssembly::DROP_V128;
99 if (RC == &WebAssembly::FUNCREFRegClass)
100 return WebAssembly::DROP_FUNCREF;
101 if (RC == &WebAssembly::EXTERNREFRegClass)
102 return WebAssembly::DROP_EXTERNREF;
108 if (RC == &WebAssembly::I32RegClass)
109 return WebAssembly::LOCAL_GET_I32;
110 if (RC == &WebAssembly::I64RegClass)
111 return WebAssembly::LOCAL_GET_I64;
112 if (RC == &WebAssembly::F32RegClass)
113 return WebAssembly::LOCAL_GET_F32;
114 if (RC == &WebAssembly::F64RegClass)
115 return WebAssembly::LOCAL_GET_F64;
116 if (RC == &WebAssembly::V128RegClass)
117 return WebAssembly::LOCAL_GET_V128;
118 if (RC == &WebAssembly::FUNCREFRegClass)
119 return WebAssembly::LOCAL_GET_FUNCREF;
120 if (RC == &WebAssembly::EXTERNREFRegClass)
121 return WebAssembly::LOCAL_GET_EXTERNREF;
127 if (RC == &WebAssembly::I32RegClass)
128 return WebAssembly::LOCAL_SET_I32;
129 if (RC == &WebAssembly::I64RegClass)
130 return WebAssembly::LOCAL_SET_I64;
131 if (RC == &WebAssembly::F32RegClass)
132 return WebAssembly::LOCAL_SET_F32;
133 if (RC == &WebAssembly::F64RegClass)
134 return WebAssembly::LOCAL_SET_F64;
135 if (RC == &WebAssembly::V128RegClass)
136 return WebAssembly::LOCAL_SET_V128;
137 if (RC == &WebAssembly::FUNCREFRegClass)
138 return WebAssembly::LOCAL_SET_FUNCREF;
139 if (RC == &WebAssembly::EXTERNREFRegClass)
140 return WebAssembly::LOCAL_SET_EXTERNREF;
146 if (RC == &WebAssembly::I32RegClass)
147 return WebAssembly::LOCAL_TEE_I32;
148 if (RC == &WebAssembly::I64RegClass)
149 return WebAssembly::LOCAL_TEE_I64;
150 if (RC == &WebAssembly::F32RegClass)
151 return WebAssembly::LOCAL_TEE_F32;
152 if (RC == &WebAssembly::F64RegClass)
153 return WebAssembly::LOCAL_TEE_F64;
154 if (RC == &WebAssembly::V128RegClass)
155 return WebAssembly::LOCAL_TEE_V128;
156 if (RC == &WebAssembly::FUNCREFRegClass)
157 return WebAssembly::LOCAL_TEE_FUNCREF;
158 if (RC == &WebAssembly::EXTERNREFRegClass)
159 return WebAssembly::LOCAL_TEE_EXTERNREF;
165 if (RC == &WebAssembly::I32RegClass)
167 if (RC == &WebAssembly::I64RegClass)
169 if (RC == &WebAssembly::F32RegClass)
171 if (RC == &WebAssembly::F64RegClass)
173 if (RC == &WebAssembly::V128RegClass)
175 if (RC == &WebAssembly::FUNCREFRegClass)
177 if (RC == &WebAssembly::EXTERNREFRegClass)
192 for (
auto DefReg :
Def->defs()) {
209 bool WebAssemblyExplicitLocals::runOnMachineFunction(
MachineFunction &MF) {
210 LLVM_DEBUG(
dbgs() <<
"********** Make Locals Explicit **********\n"
211 "********** Function: "
214 bool Changed =
false;
231 auto Local =
static_cast<unsigned>(
MI.getOperand(1).getImm());
238 MI.eraseFromParent();
244 unsigned CurLocal =
static_cast<unsigned>(MFI.
getParams().size());
245 CurLocal +=
static_cast<unsigned>(MFI.
getLocals().size());
258 if (
MI.isDebugInstr() ||
MI.isLabel())
261 if (
MI.getOpcode() == WebAssembly::IMPLICIT_DEF) {
262 MI.eraseFromParent();
278 unsigned LocalId =
getLocalId(Reg2Local, MFI, CurLocal, OldReg);
283 MI.getOperand(2).setReg(NewReg);
289 getLocalId(Reg2Local, MFI, CurLocal,
MI.getOperand(1).getReg());
292 MI.getOperand(0).getReg())
298 MI.eraseFromParent();
304 for (
auto &
Def :
MI.defs()) {
309 auto InsertPt = std::next(
MI.getIterator());
316 Drop->getOperand(0).setIsKill();
320 unsigned LocalId =
getLocalId(Reg2Local, MFI, CurLocal, OldReg);
333 Def.setIsDead(
false);
352 unsigned LocalId =
getLocalId(Reg2Local, MFI, CurLocal, OldReg);
355 MI.untieRegOperand(
MI.getOperandNo(&MO));
356 MO.ChangeToImmediate(LocalId);
369 if (
MI.isInlineAsm()) {
370 unsigned LocalId =
getLocalId(Reg2Local, MFI, CurLocal, OldReg);
372 MI.untieRegOperand(
MI.getOperandNo(&MO));
373 MO.ChangeToImmediate(LocalId);
378 unsigned LocalId =
getLocalId(Reg2Local, MFI, CurLocal, OldReg);
398 MI.getOperand(0).getReg());
399 MI.eraseFromParent();
411 if (RL == Reg2Local.
end() || RL->second < MFI.
getParams().size())
423 if (
MI.isDebugInstr() ||
MI.isLabel())
429 "WebAssemblyExplicitLocals failed to stackify a register operand");
bool isArgument(unsigned Opc)
static void checkFrameBase(WebAssemblyFunctionInfo &MFI, unsigned Local, unsigned Reg)
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
This is an optimization pass for GlobalISel generic memory operations.
const std::vector< MVT > & getLocals() const
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
static unsigned getDropOpcode(const TargetRegisterClass *RC)
Get the appropriate drop opcode for the given register class.
FunctionPass * createWebAssemblyExplicitLocals()
Reg
All possible values of the reg field in the ModR/M byte.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
static unsigned getLocalGetOpcode(const TargetRegisterClass *RC)
Get the appropriate local.get opcode for the given register class.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
void clearFrameBaseVreg()
static unsigned getLocalId(DenseMap< unsigned, unsigned > &Reg2Local, WebAssemblyFunctionInfo &MFI, unsigned &CurLocal, unsigned Reg)
Return a local id number for the given register, assigning it a new one if it doesn't yet have one.
Represent the analysis usage information of a pass.
const HexagonInstrInfo * TII
MachineOperand class - Representation of each machine instruction operand.
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
static MVT typeForRegClass(const TargetRegisterClass *RC)
Get the type associated with the given register class.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void stackifyVReg(MachineRegisterInfo &MRI, unsigned VReg)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Representation of each machine instruction.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
bool isVRegStackified(unsigned VReg) const
iterator find(const_arg_type_t< KeyT > Val)
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Register getReg() const
getReg - Returns the register number.
INITIALIZE_PASS(WebAssemblyExplicitLocals, DEBUG_TYPE, "Convert registers to WebAssembly locals", false, false) FunctionPass *llvm
void setFrameBaseLocal(unsigned Local)
void setPreservesCFG()
This function should be called by the pass, iff they do not:
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static unsigned getLocalSetOpcode(const TargetRegisterClass *RC)
Get the appropriate local.set opcode for the given register class.
void setNumLocals(size_t NumLocals)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
static MachineInstr * findStartOfTree(MachineOperand &MO, MachineRegisterInfo &MRI, const WebAssemblyFunctionInfo &MFI)
Given a MachineOperand of a stackified vreg, return the instruction at the start of the expression tr...
bool isFrameBaseVirtual() const
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
const std::vector< MVT > & getParams() const
void setLocal(size_t i, MVT VT)
auto reverse(ContainerTy &&C)
FunctionPass class - This class is used to implement most global optimizations.
unsigned getFrameBaseVreg() const
static unsigned virtReg2Index(Register Reg)
Convert a virtual register number to a 0-based index.
static unsigned getLocalTeeOpcode(const TargetRegisterClass *RC)
Get the appropriate local.tee opcode for the given register class.
void replaceWithLocal(unsigned LocalId)
bool isCopy(unsigned Opc)