32 #define DEBUG_TYPE "wasm-explicit-locals" 40 cl::desc(
"WebAssembly: output implicit locals in" 41 " instruction output for test purposes only."),
47 return "WebAssembly Explicit Locals";
66 "Convert registers to WebAssembly locals",
false,
false)
69 return new WebAssemblyExplicitLocals();
75 unsigned &CurLocal,
unsigned Reg) {
76 auto P = Reg2Local.
insert(std::make_pair(Reg, CurLocal));
79 return P.first->second;
84 if (RC == &WebAssembly::I32RegClass)
85 return WebAssembly::DROP_I32;
86 if (RC == &WebAssembly::I64RegClass)
87 return WebAssembly::DROP_I64;
88 if (RC == &WebAssembly::F32RegClass)
89 return WebAssembly::DROP_F32;
90 if (RC == &WebAssembly::F64RegClass)
91 return WebAssembly::DROP_F64;
92 if (RC == &WebAssembly::V128RegClass)
93 return WebAssembly::DROP_V128;
94 if (RC == &WebAssembly::EXCEPT_REFRegClass)
95 return WebAssembly::DROP_EXCEPT_REF;
101 if (RC == &WebAssembly::I32RegClass)
102 return WebAssembly::LOCAL_GET_I32;
103 if (RC == &WebAssembly::I64RegClass)
104 return WebAssembly::LOCAL_GET_I64;
105 if (RC == &WebAssembly::F32RegClass)
106 return WebAssembly::LOCAL_GET_F32;
107 if (RC == &WebAssembly::F64RegClass)
108 return WebAssembly::LOCAL_GET_F64;
109 if (RC == &WebAssembly::V128RegClass)
110 return WebAssembly::LOCAL_GET_V128;
111 if (RC == &WebAssembly::EXCEPT_REFRegClass)
112 return WebAssembly::LOCAL_GET_EXCEPT_REF;
118 if (RC == &WebAssembly::I32RegClass)
119 return WebAssembly::LOCAL_SET_I32;
120 if (RC == &WebAssembly::I64RegClass)
121 return WebAssembly::LOCAL_SET_I64;
122 if (RC == &WebAssembly::F32RegClass)
123 return WebAssembly::LOCAL_SET_F32;
124 if (RC == &WebAssembly::F64RegClass)
125 return WebAssembly::LOCAL_SET_F64;
126 if (RC == &WebAssembly::V128RegClass)
127 return WebAssembly::LOCAL_SET_V128;
128 if (RC == &WebAssembly::EXCEPT_REFRegClass)
129 return WebAssembly::LOCAL_SET_EXCEPT_REF;
135 if (RC == &WebAssembly::I32RegClass)
136 return WebAssembly::LOCAL_TEE_I32;
137 if (RC == &WebAssembly::I64RegClass)
138 return WebAssembly::LOCAL_TEE_I64;
139 if (RC == &WebAssembly::F32RegClass)
140 return WebAssembly::LOCAL_TEE_F32;
141 if (RC == &WebAssembly::F64RegClass)
142 return WebAssembly::LOCAL_TEE_F64;
143 if (RC == &WebAssembly::V128RegClass)
144 return WebAssembly::LOCAL_TEE_V128;
145 if (RC == &WebAssembly::EXCEPT_REFRegClass)
146 return WebAssembly::LOCAL_TEE_EXCEPT_REF;
152 if (RC == &WebAssembly::I32RegClass)
154 if (RC == &WebAssembly::I64RegClass)
156 if (RC == &WebAssembly::F32RegClass)
158 if (RC == &WebAssembly::F64RegClass)
160 if (RC == &WebAssembly::V128RegClass)
162 if (RC == &WebAssembly::EXCEPT_REFRegClass)
187 bool WebAssemblyExplicitLocals::runOnMachineFunction(
MachineFunction &MF) {
188 LLVM_DEBUG(
dbgs() <<
"********** Make Locals Explicit **********\n" 189 "********** Function: " 196 bool Changed =
false;
219 unsigned CurLocal =
static_cast<unsigned>(MFI.
getParams().size());
247 unsigned LocalId =
getLocalId(Reg2Local, CurLocal, OldReg);
279 if (MI.
getOpcode() == WebAssembly::IMPLICIT_DEF) {
292 unsigned LocalId =
getLocalId(Reg2Local, CurLocal, OldReg);
314 unsigned OldReg = MO.getReg();
321 unsigned LocalId =
getLocalId(Reg2Local, CurLocal, OldReg);
325 MO.ChangeToImmediate(LocalId);
339 unsigned LocalId =
getLocalId(Reg2Local, CurLocal, OldReg);
342 MO.ChangeToImmediate(LocalId);
347 unsigned LocalId =
getLocalId(Reg2Local, CurLocal, OldReg);
374 auto RL = Reg2Local.
find(Reg);
375 if (RL == Reg2Local.
end() || RL->second < MFI.
getParams().size())
387 if (
MI.isDebugInstr() ||
MI.isLabel())
391 (!MO.isReg() || MRI.
use_empty(MO.getReg()) ||
393 "WebAssemblyExplicitLocals failed to stackify a register operand");
static unsigned getLocalId(DenseMap< unsigned, unsigned > &Reg2Local, 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...
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
bool isLabel() const
Returns true if the MachineInstr represents a label.
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
static unsigned virtReg2Index(unsigned Reg)
Convert a virtual register number to a 0-based index.
This class represents lattice values for constants.
static unsigned index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
unsigned getReg() const
getReg - Returns the register number.
unsigned getOperandNo(const_mop_iterator I) const
Returns the number of the operand iterator I points to.
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
void setIsDead(bool Val=true)
static unsigned getSetLocalOpcode(const TargetRegisterClass *RC)
Get the appropriate local.set opcode for the given register class.
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end...
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
INLINEASM - Represents an inline asm block.
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
static unsigned getDropOpcode(const TargetRegisterClass *RC)
Get the appropriate drop opcode for the given register class.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
void untieRegOperand(unsigned OpIdx)
Break any tie involving OpIdx.
bool isVRegStackified(unsigned VReg) const
bool isCopy(const MachineInstr &MI)
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
iterator find(const_arg_type_t< KeyT > Val)
This file contains the declaration of the WebAssembly-specific utility functions. ...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file provides WebAssembly-specific target descriptions.
void setNumLocals(size_t NumLocals)
Represent the analysis usage information of a pass.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
static unsigned getGetLocalOpcode(const TargetRegisterClass *RC)
Get the appropriate local.get opcode for the given register class.
FunctionPass class - This class is used to implement most global optimizations.
void stackifyVReg(unsigned VReg)
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
bool isDebugInstr() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
iterator_range< mop_iterator > explicit_uses()
void setIsKill(bool Val=true)
This file declares the WebAssembly-specific subclass of TargetSubtarget.
bool isTee(const MachineInstr &MI)
bool isArgument(const MachineInstr &MI)
MachineOperand class - Representation of each machine instruction operand.
void setLocal(size_t i, MVT VT)
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static unsigned getTeeLocalOpcode(const TargetRegisterClass *RC)
Get the appropriate local.tee opcode for the given register class.
INITIALIZE_PASS(WebAssemblyExplicitLocals, DEBUG_TYPE, "Convert registers to WebAssembly locals", false, false) FunctionPass *llvm
bool use_empty(unsigned RegNo) const
use_empty - Return true if there are no instructions using the specified register.
static MachineInstr * findStartOfTree(MachineOperand &MO, MachineRegisterInfo &MRI, WebAssemblyFunctionInfo &MFI)
Given a MachineOperand of a stackified vreg, return the instruction at the start of the expression tr...
void replaceRegWith(unsigned FromReg, unsigned ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
This file declares WebAssembly-specific per-machine-function information.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static MVT typeForRegClass(const TargetRegisterClass *RC)
Get the type associated with the given register class.
StringRef - Represent a constant reference to a string, i.e.
const std::vector< MVT > & getParams() const
static cl::opt< bool > WasmDisableExplicitLocals("wasm-disable-explicit-locals", cl::Hidden, cl::desc("WebAssembly: output implicit locals in" " instruction output for test purposes only."), cl::init(false))
const MachineOperand & getOperand(unsigned i) const
FunctionPass * createWebAssemblyExplicitLocals()
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...