35#define DEBUG_TYPE "wasm-explicit-locals"
40 return "WebAssembly Explicit Locals";
57char WebAssemblyExplicitLocalsLegacy::ID = 0;
59 "Convert registers to WebAssembly locals",
false,
false)
62 return new WebAssemblyExplicitLocalsLegacy();
70 dbgs() <<
"Allocating local " <<
Local <<
"for VReg "
82 auto P = Reg2Local.
insert(std::make_pair(
Reg, CurLocal));
87 return P.first->second;
92 if (RC == &WebAssembly::I32RegClass)
93 return WebAssembly::DROP_I32;
94 if (RC == &WebAssembly::I64RegClass)
95 return WebAssembly::DROP_I64;
96 if (RC == &WebAssembly::F32RegClass)
97 return WebAssembly::DROP_F32;
98 if (RC == &WebAssembly::F64RegClass)
99 return WebAssembly::DROP_F64;
100 if (RC == &WebAssembly::V128RegClass)
101 return WebAssembly::DROP_V128;
102 if (RC == &WebAssembly::FUNCREFRegClass)
103 return WebAssembly::DROP_FUNCREF;
104 if (RC == &WebAssembly::EXTERNREFRegClass)
105 return WebAssembly::DROP_EXTERNREF;
106 if (RC == &WebAssembly::EXNREFRegClass)
107 return WebAssembly::DROP_EXNREF;
113 if (RC == &WebAssembly::I32RegClass)
114 return WebAssembly::LOCAL_GET_I32;
115 if (RC == &WebAssembly::I64RegClass)
116 return WebAssembly::LOCAL_GET_I64;
117 if (RC == &WebAssembly::F32RegClass)
118 return WebAssembly::LOCAL_GET_F32;
119 if (RC == &WebAssembly::F64RegClass)
120 return WebAssembly::LOCAL_GET_F64;
121 if (RC == &WebAssembly::V128RegClass)
122 return WebAssembly::LOCAL_GET_V128;
123 if (RC == &WebAssembly::FUNCREFRegClass)
124 return WebAssembly::LOCAL_GET_FUNCREF;
125 if (RC == &WebAssembly::EXTERNREFRegClass)
126 return WebAssembly::LOCAL_GET_EXTERNREF;
127 if (RC == &WebAssembly::EXNREFRegClass)
128 return WebAssembly::LOCAL_GET_EXNREF;
134 if (RC == &WebAssembly::I32RegClass)
135 return WebAssembly::LOCAL_SET_I32;
136 if (RC == &WebAssembly::I64RegClass)
137 return WebAssembly::LOCAL_SET_I64;
138 if (RC == &WebAssembly::F32RegClass)
139 return WebAssembly::LOCAL_SET_F32;
140 if (RC == &WebAssembly::F64RegClass)
141 return WebAssembly::LOCAL_SET_F64;
142 if (RC == &WebAssembly::V128RegClass)
143 return WebAssembly::LOCAL_SET_V128;
144 if (RC == &WebAssembly::FUNCREFRegClass)
145 return WebAssembly::LOCAL_SET_FUNCREF;
146 if (RC == &WebAssembly::EXTERNREFRegClass)
147 return WebAssembly::LOCAL_SET_EXTERNREF;
148 if (RC == &WebAssembly::EXNREFRegClass)
149 return WebAssembly::LOCAL_SET_EXNREF;
155 if (RC == &WebAssembly::I32RegClass)
156 return WebAssembly::LOCAL_TEE_I32;
157 if (RC == &WebAssembly::I64RegClass)
158 return WebAssembly::LOCAL_TEE_I64;
159 if (RC == &WebAssembly::F32RegClass)
160 return WebAssembly::LOCAL_TEE_F32;
161 if (RC == &WebAssembly::F64RegClass)
162 return WebAssembly::LOCAL_TEE_F64;
163 if (RC == &WebAssembly::V128RegClass)
164 return WebAssembly::LOCAL_TEE_V128;
165 if (RC == &WebAssembly::FUNCREFRegClass)
166 return WebAssembly::LOCAL_TEE_FUNCREF;
167 if (RC == &WebAssembly::EXTERNREFRegClass)
168 return WebAssembly::LOCAL_TEE_EXTERNREF;
169 if (RC == &WebAssembly::EXNREFRegClass)
170 return WebAssembly::LOCAL_TEE_EXNREF;
176 if (RC == &WebAssembly::I32RegClass)
178 if (RC == &WebAssembly::I64RegClass)
180 if (RC == &WebAssembly::F32RegClass)
182 if (RC == &WebAssembly::F64RegClass)
184 if (RC == &WebAssembly::V128RegClass)
186 if (RC == &WebAssembly::FUNCREFRegClass)
188 if (RC == &WebAssembly::EXTERNREFRegClass)
189 return MVT::externref;
190 if (RC == &WebAssembly::EXNREFRegClass)
205 for (
auto DefReg : Def->defs()) {
230 for (
auto *
MI : ToDelete)
231 MI->eraseFromParent();
235 LLVM_DEBUG(
dbgs() <<
"********** Make Locals Explicit **********\n"
236 "********** Function: "
258 auto Local =
static_cast<unsigned>(
MI.getOperand(1).
getImm());
265 MI.eraseFromParent();
271 unsigned CurLocal =
static_cast<unsigned>(MFI.
getParams().
size());
293 if (
MI.isDebugInstr() ||
MI.isLabel())
296 if (
MI.getOpcode() == WebAssembly::IMPLICIT_DEF) {
297 MI.eraseFromParent();
340 unsigned LocalId =
getLocalId(Reg2Local, MFI, CurLocal, DefReg);
345 MI.getOperand(2).setReg(NewReg);
351 getLocalId(Reg2Local, MFI, CurLocal,
MI.getOperand(1).getReg());
354 MI.getOperand(0).getReg())
360 MI.eraseFromParent();
366 for (
auto &Def :
MI.defs()) {
371 auto InsertPt = std::next(
MI.getIterator());
375 bool NeedsRegForDebug =
379 if (UseEmpty[OldReg.
virtRegIndex()] && !NeedsRegForDebug) {
385 Drop->getOperand(0).setIsKill();
389 unsigned LocalId =
getLocalId(Reg2Local, MFI, CurLocal, OldReg);
402 Def.setIsDead(
false);
421 unsigned LocalId =
getLocalId(Reg2Local, MFI, CurLocal, OldReg);
424 MI.untieRegOperand(MO.getOperandNo());
425 MO.ChangeToImmediate(LocalId);
438 if (
MI.isInlineAsm()) {
439 unsigned LocalId =
getLocalId(Reg2Local, MFI, CurLocal, OldReg);
441 MI.untieRegOperand(MO.getOperandNo());
442 MO.ChangeToImmediate(LocalId);
447 unsigned LocalId =
getLocalId(Reg2Local, MFI, CurLocal, OldReg);
467 MI.getOperand(0).getReg());
468 MI.eraseFromParent();
480 if (RL == Reg2Local.
end() || RL->second < MFI.
getParams().size())
492 if (
MI.isDebugInstr() ||
MI.isLabel())
496 (!MO.isReg() || MRI.
use_empty(MO.getReg()) ||
498 "WebAssemblyExplicitLocals failed to stackify a register operand");
507bool WebAssemblyExplicitLocalsLegacy::runOnMachineFunction(
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file contains the declaration of the WebAssembly-specific manager for DebugValues associated wit...
static unsigned getLocalGetOpcode(const TargetRegisterClass *RC)
Get the appropriate local.get opcode for the given register class.
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.
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...
static bool explicitLocals(MachineFunction &MF)
static MVT typeForRegClass(const TargetRegisterClass *RC)
Get the type associated with the given register class.
static unsigned getLocalTeeOpcode(const TargetRegisterClass *RC)
Get the appropriate local.tee opcode for the given register class.
static void checkFrameBase(WebAssemblyFunctionInfo &MFI, unsigned Local, unsigned Reg)
static unsigned getLocalSetOpcode(const TargetRegisterClass *RC)
Get the appropriate local.set opcode for the given register class.
static unsigned getDropOpcode(const TargetRegisterClass *RC)
Get the appropriate drop opcode for the given register class.
static void removeFakeUses(MachineFunction &MF)
This file provides WebAssembly-specific target descriptions.
This file declares WebAssembly-specific per-machine-function information.
This file declares the WebAssembly-specific subclass of TargetSubtarget.
This file contains the declaration of the WebAssembly-specific utility functions.
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end.
Represent the analysis usage information of a pass.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
FunctionPass class - This class is used to implement most global optimizations.
DISubprogram * getSubprogram() const
Get the attached subprogram.
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Representation of each machine instruction.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
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,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Wrapper class representing virtual and physical registers.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
unsigned virtRegIndex() const
Convert a virtual register number to a 0-based index.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
void replaceWithLocal(unsigned LocalId)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
void stackifyVReg(MachineRegisterInfo &MRI, Register VReg)
void setLocal(size_t i, MVT VT)
void setNumLocals(size_t NumLocals)
unsigned getFrameBaseVreg() const
void setFrameBaseLocal(unsigned Local)
bool isVRegStackified(Register VReg) const
const std::vector< MVT > & getLocals() const
void clearFrameBaseVreg()
bool isFrameBaseVirtual() const
void unstackifyVReg(Register VReg)
const std::vector< MVT > & getParams() const
Pass manager infrastructure for declaring and invalidating analyses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
bool isArgument(unsigned Opc)
bool isCopy(unsigned Opc)
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createWebAssemblyExplicitLocalsLegacyPass()
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
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...
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
auto reverse(ContainerTy &&C)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
MCRegisterClass TargetRegisterClass