LLVM  13.0.0git
WebAssemblyExplicitLocals.cpp
Go to the documentation of this file.
1 //===-- WebAssemblyExplicitLocals.cpp - Make Locals Explicit --------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file converts any remaining registers into WebAssembly locals.
11 ///
12 /// After register stackification and register coloring, convert non-stackified
13 /// registers into locals, inserting explicit local.get and local.set
14 /// instructions.
15 ///
16 //===----------------------------------------------------------------------===//
17 
19 #include "WebAssembly.h"
22 #include "WebAssemblySubtarget.h"
23 #include "WebAssemblyUtilities.h"
27 #include "llvm/CodeGen/Passes.h"
28 #include "llvm/Support/Debug.h"
30 using namespace llvm;
31 
32 #define DEBUG_TYPE "wasm-explicit-locals"
33 
34 namespace {
35 class WebAssemblyExplicitLocals final : public MachineFunctionPass {
36  StringRef getPassName() const override {
37  return "WebAssembly Explicit Locals";
38  }
39 
40  void getAnalysisUsage(AnalysisUsage &AU) const override {
41  AU.setPreservesCFG();
44  }
45 
46  bool runOnMachineFunction(MachineFunction &MF) override;
47 
48 public:
49  static char ID; // Pass identification, replacement for typeid
50  WebAssemblyExplicitLocals() : MachineFunctionPass(ID) {}
51 };
52 } // end anonymous namespace
53 
55 INITIALIZE_PASS(WebAssemblyExplicitLocals, DEBUG_TYPE,
56  "Convert registers to WebAssembly locals", false, false)
57 
59  return new WebAssemblyExplicitLocals();
60 }
61 
62 static void checkFrameBase(WebAssemblyFunctionInfo &MFI, unsigned Local,
63  unsigned Reg) {
64  // Mark a local for the frame base vreg.
65  if (MFI.isFrameBaseVirtual() && Reg == MFI.getFrameBaseVreg()) {
66  LLVM_DEBUG({
67  dbgs() << "Allocating local " << Local << "for VReg "
68  << Register::virtReg2Index(Reg) << '\n';
69  });
70  MFI.setFrameBaseLocal(Local);
71  }
72 }
73 
74 /// Return a local id number for the given register, assigning it a new one
75 /// if it doesn't yet have one.
76 static unsigned getLocalId(DenseMap<unsigned, unsigned> &Reg2Local,
77  WebAssemblyFunctionInfo &MFI, unsigned &CurLocal,
78  unsigned Reg) {
79  auto P = Reg2Local.insert(std::make_pair(Reg, CurLocal));
80  if (P.second) {
81  checkFrameBase(MFI, CurLocal, Reg);
82  ++CurLocal;
83  }
84  return P.first->second;
85 }
86 
87 /// Get the appropriate drop opcode for the given register class.
88 static unsigned getDropOpcode(const TargetRegisterClass *RC) {
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;
103  llvm_unreachable("Unexpected register class");
104 }
105 
106 /// Get the appropriate local.get opcode for the given register class.
107 static unsigned getLocalGetOpcode(const TargetRegisterClass *RC) {
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;
122  llvm_unreachable("Unexpected register class");
123 }
124 
125 /// Get the appropriate local.set opcode for the given register class.
126 static unsigned getLocalSetOpcode(const TargetRegisterClass *RC) {
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;
141  llvm_unreachable("Unexpected register class");
142 }
143 
144 /// Get the appropriate local.tee opcode for the given register class.
145 static unsigned getLocalTeeOpcode(const TargetRegisterClass *RC) {
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;
160  llvm_unreachable("Unexpected register class");
161 }
162 
163 /// Get the type associated with the given register class.
165  if (RC == &WebAssembly::I32RegClass)
166  return MVT::i32;
167  if (RC == &WebAssembly::I64RegClass)
168  return MVT::i64;
169  if (RC == &WebAssembly::F32RegClass)
170  return MVT::f32;
171  if (RC == &WebAssembly::F64RegClass)
172  return MVT::f64;
173  if (RC == &WebAssembly::V128RegClass)
174  return MVT::v16i8;
175  if (RC == &WebAssembly::FUNCREFRegClass)
176  return MVT::funcref;
177  if (RC == &WebAssembly::EXTERNREFRegClass)
178  return MVT::externref;
179  llvm_unreachable("unrecognized register class");
180 }
181 
182 /// Given a MachineOperand of a stackified vreg, return the instruction at the
183 /// start of the expression tree.
186  const WebAssemblyFunctionInfo &MFI) {
187  Register Reg = MO.getReg();
190 
191  // If this instruction has any non-stackified defs, it is the start
192  for (auto DefReg : Def->defs()) {
193  if (!MFI.isVRegStackified(DefReg.getReg())) {
194  return Def;
195  }
196  }
197 
198  // Find the first stackified use and proceed from there.
199  for (MachineOperand &DefMO : Def->explicit_uses()) {
200  if (!DefMO.isReg())
201  continue;
202  return findStartOfTree(DefMO, MRI, MFI);
203  }
204 
205  // If there were no stackified uses, we've reached the start.
206  return Def;
207 }
208 
209 bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
210  LLVM_DEBUG(dbgs() << "********** Make Locals Explicit **********\n"
211  "********** Function: "
212  << MF.getName() << '\n');
213 
214  bool Changed = false;
217  const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
218 
219  // Map non-stackified virtual registers to their local ids.
221 
222  // Handle ARGUMENTS first to ensure that they get the designated numbers.
223  for (MachineBasicBlock::iterator I = MF.begin()->begin(),
224  E = MF.begin()->end();
225  I != E;) {
226  MachineInstr &MI = *I++;
227  if (!WebAssembly::isArgument(MI.getOpcode()))
228  break;
229  Register Reg = MI.getOperand(0).getReg();
230  assert(!MFI.isVRegStackified(Reg));
231  auto Local = static_cast<unsigned>(MI.getOperand(1).getImm());
232  Reg2Local[Reg] = Local;
233  checkFrameBase(MFI, Local, Reg);
234 
235  // Update debug value to point to the local before removing.
237 
238  MI.eraseFromParent();
239  Changed = true;
240  }
241 
242  // Start assigning local numbers after the last parameter.
243  unsigned CurLocal = static_cast<unsigned>(MFI.getParams().size());
244 
245  // Precompute the set of registers that are unused, so that we can insert
246  // drops to their defs.
247  BitVector UseEmpty(MRI.getNumVirtRegs());
248  for (unsigned I = 0, E = MRI.getNumVirtRegs(); I < E; ++I)
249  UseEmpty[I] = MRI.use_empty(Register::index2VirtReg(I));
250 
251  // Visit each instruction in the function.
252  for (MachineBasicBlock &MBB : MF) {
253  for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E;) {
254  MachineInstr &MI = *I++;
255  assert(!WebAssembly::isArgument(MI.getOpcode()));
256 
257  if (MI.isDebugInstr() || MI.isLabel())
258  continue;
259 
260  if (MI.getOpcode() == WebAssembly::IMPLICIT_DEF) {
261  MI.eraseFromParent();
262  Changed = true;
263  continue;
264  }
265 
266  // Replace tee instructions with local.tee. The difference is that tee
267  // instructions have two defs, while local.tee instructions have one def
268  // and an index of a local to write to.
269  if (WebAssembly::isTee(MI.getOpcode())) {
270  assert(MFI.isVRegStackified(MI.getOperand(0).getReg()));
271  assert(!MFI.isVRegStackified(MI.getOperand(1).getReg()));
272  Register OldReg = MI.getOperand(2).getReg();
273  const TargetRegisterClass *RC = MRI.getRegClass(OldReg);
274 
275  // Stackify the input if it isn't stackified yet.
276  if (!MFI.isVRegStackified(OldReg)) {
277  unsigned LocalId = getLocalId(Reg2Local, MFI, CurLocal, OldReg);
278  Register NewReg = MRI.createVirtualRegister(RC);
279  unsigned Opc = getLocalGetOpcode(RC);
280  BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(Opc), NewReg)
281  .addImm(LocalId);
282  MI.getOperand(2).setReg(NewReg);
283  MFI.stackifyVReg(MRI, NewReg);
284  }
285 
286  // Replace the TEE with a LOCAL_TEE.
287  unsigned LocalId =
288  getLocalId(Reg2Local, MFI, CurLocal, MI.getOperand(1).getReg());
289  unsigned Opc = getLocalTeeOpcode(RC);
290  BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(Opc),
291  MI.getOperand(0).getReg())
292  .addImm(LocalId)
293  .addReg(MI.getOperand(2).getReg());
294 
296 
297  MI.eraseFromParent();
298  Changed = true;
299  continue;
300  }
301 
302  // Insert local.sets for any defs that aren't stackified yet.
303  for (auto &Def : MI.defs()) {
304  Register OldReg = Def.getReg();
305  if (!MFI.isVRegStackified(OldReg)) {
306  const TargetRegisterClass *RC = MRI.getRegClass(OldReg);
307  Register NewReg = MRI.createVirtualRegister(RC);
308  auto InsertPt = std::next(MI.getIterator());
309  if (UseEmpty[Register::virtReg2Index(OldReg)]) {
310  unsigned Opc = getDropOpcode(RC);
311  MachineInstr *Drop =
312  BuildMI(MBB, InsertPt, MI.getDebugLoc(), TII->get(Opc))
313  .addReg(NewReg);
314  // After the drop instruction, this reg operand will not be used
315  Drop->getOperand(0).setIsKill();
316  if (MFI.isFrameBaseVirtual() && OldReg == MFI.getFrameBaseVreg())
317  MFI.clearFrameBaseVreg();
318  } else {
319  unsigned LocalId = getLocalId(Reg2Local, MFI, CurLocal, OldReg);
320  unsigned Opc = getLocalSetOpcode(RC);
321 
323 
324  BuildMI(MBB, InsertPt, MI.getDebugLoc(), TII->get(Opc))
325  .addImm(LocalId)
326  .addReg(NewReg);
327  }
328  // This register operand of the original instruction is now being used
329  // by the inserted drop or local.set instruction, so make it not dead
330  // yet.
331  Def.setReg(NewReg);
332  Def.setIsDead(false);
333  MFI.stackifyVReg(MRI, NewReg);
334  Changed = true;
335  }
336  }
337 
338  // Insert local.gets for any uses that aren't stackified yet.
339  MachineInstr *InsertPt = &MI;
340  for (MachineOperand &MO : reverse(MI.explicit_uses())) {
341  if (!MO.isReg())
342  continue;
343 
344  Register OldReg = MO.getReg();
345 
346  // Inline asm may have a def in the middle of the operands. Our contract
347  // with inline asm register operands is to provide local indices as
348  // immediates.
349  if (MO.isDef()) {
350  assert(MI.isInlineAsm());
351  unsigned LocalId = getLocalId(Reg2Local, MFI, CurLocal, OldReg);
352  // If this register operand is tied to another operand, we can't
353  // change it to an immediate. Untie it first.
354  MI.untieRegOperand(MI.getOperandNo(&MO));
355  MO.ChangeToImmediate(LocalId);
356  continue;
357  }
358 
359  // If we see a stackified register, prepare to insert subsequent
360  // local.gets before the start of its tree.
361  if (MFI.isVRegStackified(OldReg)) {
362  InsertPt = findStartOfTree(MO, MRI, MFI);
363  continue;
364  }
365 
366  // Our contract with inline asm register operands is to provide local
367  // indices as immediates.
368  if (MI.isInlineAsm()) {
369  unsigned LocalId = getLocalId(Reg2Local, MFI, CurLocal, OldReg);
370  // Untie it first if this reg operand is tied to another operand.
371  MI.untieRegOperand(MI.getOperandNo(&MO));
372  MO.ChangeToImmediate(LocalId);
373  continue;
374  }
375 
376  // Insert a local.get.
377  unsigned LocalId = getLocalId(Reg2Local, MFI, CurLocal, OldReg);
378  const TargetRegisterClass *RC = MRI.getRegClass(OldReg);
379  Register NewReg = MRI.createVirtualRegister(RC);
380  unsigned Opc = getLocalGetOpcode(RC);
381  InsertPt =
382  BuildMI(MBB, InsertPt, MI.getDebugLoc(), TII->get(Opc), NewReg)
383  .addImm(LocalId);
384  MO.setReg(NewReg);
385  MFI.stackifyVReg(MRI, NewReg);
386  Changed = true;
387  }
388 
389  // Coalesce and eliminate COPY instructions.
390  if (WebAssembly::isCopy(MI.getOpcode())) {
391  MRI.replaceRegWith(MI.getOperand(1).getReg(),
392  MI.getOperand(0).getReg());
393  MI.eraseFromParent();
394  Changed = true;
395  }
396  }
397  }
398 
399  // Define the locals.
400  // TODO: Sort the locals for better compression.
401  MFI.setNumLocals(CurLocal - MFI.getParams().size());
402  for (unsigned I = 0, E = MRI.getNumVirtRegs(); I < E; ++I) {
403  unsigned Reg = Register::index2VirtReg(I);
404  auto RL = Reg2Local.find(Reg);
405  if (RL == Reg2Local.end() || RL->second < MFI.getParams().size())
406  continue;
407 
408  MFI.setLocal(RL->second - MFI.getParams().size(),
410  Changed = true;
411  }
412 
413 #ifndef NDEBUG
414  // Assert that all registers have been stackified at this point.
415  for (const MachineBasicBlock &MBB : MF) {
416  for (const MachineInstr &MI : MBB) {
417  if (MI.isDebugInstr() || MI.isLabel())
418  continue;
419  for (const MachineOperand &MO : MI.explicit_operands()) {
420  assert(
421  (!MO.isReg() || MRI.use_empty(MO.getReg()) ||
422  MFI.isVRegStackified(MO.getReg())) &&
423  "WebAssemblyExplicitLocals failed to stackify a register operand");
424  }
425  }
426  }
427 #endif
428 
429  return Changed;
430 }
llvm::WebAssembly::isArgument
bool isArgument(unsigned Opc)
Definition: WebAssemblyMCTargetDesc.h:302
checkFrameBase
static void checkFrameBase(WebAssemblyFunctionInfo &MFI, unsigned Local, unsigned Reg)
Definition: WebAssemblyExplicitLocals.cpp:62
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:100
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:132
llvm
Definition: AllocatorList.h:23
llvm::tgtok::Def
@ Def
Definition: TGLexer.h:50
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
WebAssembly.h
llvm::MachineRegisterInfo::createVirtualRegister
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Definition: MachineRegisterInfo.cpp:158
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
P
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
Definition: README-SSE.txt:411
getDropOpcode
static unsigned getDropOpcode(const TargetRegisterClass *RC)
Get the appropriate drop opcode for the given register class.
Definition: WebAssemblyExplicitLocals.cpp:88
llvm::createWebAssemblyExplicitLocals
FunctionPass * createWebAssemblyExplicitLocals()
llvm::WebAssembly::isTee
bool isTee(unsigned Opc)
Definition: WebAssemblyMCTargetDesc.h:356
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
llvm::reverse
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
Definition: STLExtras.h:338
llvm::MachineRegisterInfo::getNumVirtRegs
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
Definition: MachineRegisterInfo.h:757
llvm::Register::index2VirtReg
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition: Register.h:84
getLocalGetOpcode
static unsigned getLocalGetOpcode(const TargetRegisterClass *RC)
Get the appropriate local.get opcode for the given register class.
Definition: WebAssemblyExplicitLocals.cpp:107
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:102
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:122
MachineRegisterInfo.h
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
llvm::MVT::funcref
@ funcref
Definition: MachineValueType.h:255
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:565
llvm::MachineBlockFrequencyInfo
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
Definition: MachineBlockFrequencyInfo.h:33
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::MachineFunction::getInfo
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Definition: MachineFunction.h:653
llvm::WebAssemblyFunctionInfo::clearFrameBaseVreg
void clearFrameBaseVreg()
Definition: WebAssemblyMachineFunctionInfo.h:112
llvm::MVT::f64
@ f64
Definition: MachineValueType.h:53
getLocalId
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.
Definition: WebAssemblyExplicitLocals.cpp:76
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
llvm::MachineFunction::begin
iterator begin()
Definition: MachineFunction.h:737
llvm::ms_demangle::QualifierMangleMode::Drop
@ Drop
llvm::BitVector
Definition: BitVector.h:74
llvm::MachineRegisterInfo::getVRegDef
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Definition: MachineRegisterInfo.cpp:400
llvm::MachineRegisterInfo::use_empty
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
Definition: MachineRegisterInfo.h:506
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
typeForRegClass
static MVT typeForRegClass(const TargetRegisterClass *RC)
Get the type associated with the given register class.
Definition: WebAssemblyExplicitLocals.cpp:164
WebAssemblyUtilities.h
WebAssemblyMCTargetDesc.h
WebAssemblyDebugValueManager.h
llvm::MachineRegisterInfo::getRegClass
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
Definition: MachineRegisterInfo.h:634
Passes.h
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:555
llvm::WebAssemblyFunctionInfo::stackifyVReg
void stackifyVReg(MachineRegisterInfo &MRI, unsigned VReg)
Definition: WebAssemblyMachineFunctionInfo.h:124
llvm::MVT::v16i8
@ v16i8
Definition: MachineValueType.h:77
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::MVT::externref
@ externref
Definition: MachineValueType.h:256
DEBUG_TYPE
#define DEBUG_TYPE
Definition: WebAssemblyExplicitLocals.cpp:32
llvm::DenseMap< unsigned, unsigned >
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::WebAssemblyFunctionInfo::isVRegStackified
bool isVRegStackified(unsigned VReg) const
Definition: WebAssemblyMachineFunctionInfo.h:136
llvm::DenseMapBase::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
llvm::MachineFunction::getName
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Definition: MachineFunction.cpp:522
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::WebAssemblyFunctionInfo
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
Definition: WebAssemblyMachineFunctionInfo.h:33
llvm::MVT
Machine Value Type.
Definition: MachineValueType.h:30
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:98
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:357
WebAssemblyMachineFunctionInfo.h
llvm::MachineFunction
Definition: MachineFunction.h:227
llvm::WebAssemblyDebugValueManager
Definition: WebAssemblyDebugValueManager.h:24
INITIALIZE_PASS
INITIALIZE_PASS(WebAssemblyExplicitLocals, DEBUG_TYPE, "Convert registers to WebAssembly locals", false, false) FunctionPass *llvm
Definition: WebAssemblyExplicitLocals.cpp:55
llvm::WebAssemblyFunctionInfo::setFrameBaseLocal
void setFrameBaseLocal(unsigned Local)
Definition: WebAssemblyMachineFunctionInfo.h:115
llvm::MVT::i64
@ i64
Definition: MachineValueType.h:44
llvm::AnalysisUsage::setPreservesCFG
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:253
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::AnalysisUsage::addPreserved
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Definition: PassAnalysisSupport.h:98
llvm::WebAssemblySubtarget
Definition: WebAssemblySubtarget.h:35
getLocalSetOpcode
static unsigned getLocalSetOpcode(const TargetRegisterClass *RC)
Get the appropriate local.set opcode for the given register class.
Definition: WebAssemblyExplicitLocals.cpp:126
llvm::WebAssemblyFunctionInfo::setNumLocals
void setNumLocals(size_t NumLocals)
Definition: WebAssemblyMachineFunctionInfo.h:92
llvm::DenseMapBase::insert
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:207
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::pdb::PDB_DataKind::Local
@ Local
llvm::MachineRegisterInfo::replaceRegWith
void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
Definition: MachineRegisterInfo.cpp:380
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::DenseMapBase::end
iterator end()
Definition: DenseMap.h:83
WebAssemblySubtarget.h
findStartOfTree
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...
Definition: WebAssemblyExplicitLocals.cpp:184
llvm::MVT::i32
@ i32
Definition: MachineValueType.h:43
llvm::WebAssemblyFunctionInfo::isFrameBaseVirtual
bool isFrameBaseVirtual() const
Definition: WebAssemblyMachineFunctionInfo.h:114
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:268
MachineInstrBuilder.h
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:329
llvm::WebAssemblyFunctionInfo::getParams
const std::vector< MVT > & getParams() const
Definition: WebAssemblyMachineFunctionInfo.h:82
llvm::WebAssemblyFunctionInfo::setLocal
void setLocal(size_t i, MVT VT)
Definition: WebAssemblyMachineFunctionInfo.h:93
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
llvm::WebAssemblyFunctionInfo::getFrameBaseVreg
unsigned getFrameBaseVreg() const
Definition: WebAssemblyMachineFunctionInfo.h:108
llvm::Register::virtReg2Index
static unsigned virtReg2Index(Register Reg)
Convert a virtual register number to a 0-based index.
Definition: Register.h:77
getLocalTeeOpcode
static unsigned getLocalTeeOpcode(const TargetRegisterClass *RC)
Get the appropriate local.tee opcode for the given register class.
Definition: WebAssemblyExplicitLocals.cpp:145
raw_ostream.h
llvm::WebAssemblyDebugValueManager::replaceWithLocal
void replaceWithLocal(unsigned LocalId)
Definition: WebAssemblyDebugValueManager.cpp:64
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::MVT::f32
@ f32
Definition: MachineValueType.h:52
MachineBlockFrequencyInfo.h
Debug.h
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:270
llvm::WebAssembly::isCopy
bool isCopy(unsigned Opc)
Definition: WebAssemblyMCTargetDesc.h:334
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38