LLVM 24.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"
29#include "llvm/CodeGen/Passes.h"
30#include "llvm/IR/Analysis.h"
31#include "llvm/Support/Debug.h"
33using namespace llvm;
34
35#define DEBUG_TYPE "wasm-explicit-locals"
36
37namespace {
38class WebAssemblyExplicitLocalsLegacy final : public MachineFunctionPass {
39 StringRef getPassName() const override {
40 return "WebAssembly Explicit Locals";
41 }
42
43 void getAnalysisUsage(AnalysisUsage &AU) const override {
44 AU.setPreservesCFG();
47 }
48
49 bool runOnMachineFunction(MachineFunction &MF) override;
50
51public:
52 static char ID; // Pass identification, replacement for typeid
53 WebAssemblyExplicitLocalsLegacy() : MachineFunctionPass(ID) {}
54};
55} // end anonymous namespace
56
57char WebAssemblyExplicitLocalsLegacy::ID = 0;
58INITIALIZE_PASS(WebAssemblyExplicitLocalsLegacy, DEBUG_TYPE,
59 "Convert registers to WebAssembly locals", false, false)
60
62 return new WebAssemblyExplicitLocalsLegacy();
63}
64
65static void checkFrameBase(WebAssemblyFunctionInfo &MFI, unsigned Local,
66 unsigned Reg) {
67 // Mark a local for the frame base vreg.
68 if (MFI.isFrameBaseVirtual() && Reg == MFI.getFrameBaseVreg()) {
70 dbgs() << "Allocating local " << Local << "for VReg "
71 << Register(Reg).virtRegIndex() << '\n';
72 });
74 }
75}
76
77/// Return a local id number for the given register, assigning it a new one
78/// if it doesn't yet have one.
79static unsigned getLocalId(DenseMap<unsigned, unsigned> &Reg2Local,
80 WebAssemblyFunctionInfo &MFI, unsigned &CurLocal,
81 unsigned Reg) {
82 auto P = Reg2Local.insert(std::make_pair(Reg, CurLocal));
83 if (P.second) {
84 checkFrameBase(MFI, CurLocal, Reg);
85 ++CurLocal;
86 }
87 return P.first->second;
88}
89
90/// Get the appropriate drop opcode for the given register class.
91static unsigned getDropOpcode(const TargetRegisterClass *RC) {
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;
108 llvm_unreachable("Unexpected register class");
109}
110
111/// Get the appropriate local.get opcode for the given register class.
112static unsigned getLocalGetOpcode(const TargetRegisterClass *RC) {
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;
129 llvm_unreachable("Unexpected register class");
130}
131
132/// Get the appropriate local.set opcode for the given register class.
133static unsigned getLocalSetOpcode(const TargetRegisterClass *RC) {
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;
150 llvm_unreachable("Unexpected register class");
151}
152
153/// Get the appropriate local.tee opcode for the given register class.
154static unsigned getLocalTeeOpcode(const TargetRegisterClass *RC) {
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;
171 llvm_unreachable("Unexpected register class");
172}
173
174/// Get the type associated with the given register class.
176 if (RC == &WebAssembly::I32RegClass)
177 return MVT::i32;
178 if (RC == &WebAssembly::I64RegClass)
179 return MVT::i64;
180 if (RC == &WebAssembly::F32RegClass)
181 return MVT::f32;
182 if (RC == &WebAssembly::F64RegClass)
183 return MVT::f64;
184 if (RC == &WebAssembly::V128RegClass)
185 return MVT::v16i8;
186 if (RC == &WebAssembly::FUNCREFRegClass)
187 return MVT::funcref;
188 if (RC == &WebAssembly::EXTERNREFRegClass)
189 return MVT::externref;
190 if (RC == &WebAssembly::EXNREFRegClass)
191 return MVT::exnref;
192 llvm_unreachable("unrecognized register class");
193}
194
195/// Given a MachineOperand of a stackified vreg, return the instruction at the
196/// start of the expression tree.
199 const WebAssemblyFunctionInfo &MFI) {
200 Register Reg = MO.getReg();
202 MachineInstr *Def = MRI.getVRegDef(Reg);
203
204 // If this instruction has any non-stackified defs, it is the start
205 for (auto DefReg : Def->defs()) {
206 if (!MFI.isVRegStackified(DefReg.getReg())) {
207 return Def;
208 }
209 }
210
211 // Find the first stackified use and proceed from there.
212 for (MachineOperand &DefMO : Def->explicit_uses()) {
213 if (!DefMO.isReg())
214 continue;
215 return findStartOfTree(DefMO, MRI, MFI);
216 }
217
218 // If there were no stackified uses, we've reached the start.
219 return Def;
220}
221
222// FAKE_USEs are no-ops, so remove them here so that the values used by them
223// will be correctly dropped later.
226 for (auto &MBB : MF)
227 for (auto &MI : MBB)
228 if (MI.isFakeUse())
229 ToDelete.push_back(&MI);
230 for (auto *MI : ToDelete)
231 MI->eraseFromParent();
232}
233
235 LLVM_DEBUG(dbgs() << "********** Make Locals Explicit **********\n"
236 "********** Function: "
237 << MF.getName() << '\n');
238
239 bool Changed = false;
242 const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
243
244 removeFakeUses(MF);
245
246 // Map non-stackified virtual registers to their local ids.
248
249 // Handle ARGUMENTS first to ensure that they get the designated numbers.
250 for (MachineBasicBlock::iterator I = MF.begin()->begin(),
251 E = MF.begin()->end();
252 I != E;) {
253 MachineInstr &MI = *I++;
254 if (!WebAssembly::isArgument(MI.getOpcode()))
255 break;
256 Register Reg = MI.getOperand(0).getReg();
258 auto Local = static_cast<unsigned>(MI.getOperand(1).getImm());
259 Reg2Local[Reg] = Local;
260 checkFrameBase(MFI, Local, Reg);
261
262 // Update debug value to point to the local before removing.
264
265 MI.eraseFromParent();
266 Changed = true;
267 }
268
269 // Start assigning local numbers after the last parameter and after any
270 // already-assigned locals.
271 unsigned CurLocal = static_cast<unsigned>(MFI.getParams().size());
272 CurLocal += static_cast<unsigned>(MFI.getLocals().size());
273
274 // Precompute the set of registers that are unused, so that we can insert
275 // drops to their defs.
276 // And unstackify any stackified registers that don't have any uses, so that
277 // they can be dropped later. This can happen when transformations after
278 // RegStackify remove instructions using stackified registers.
279 BitVector UseEmpty(MRI.getNumVirtRegs());
280 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I < E; ++I) {
282 if (MRI.use_empty(Reg)) {
283 UseEmpty[I] = true;
284 MFI.unstackifyVReg(Reg);
285 }
286 }
287
288 // Visit each instruction in the function.
289 for (MachineBasicBlock &MBB : MF) {
291 assert(!WebAssembly::isArgument(MI.getOpcode()));
292
293 if (MI.isDebugInstr() || MI.isLabel())
294 continue;
295
296 if (MI.getOpcode() == WebAssembly::IMPLICIT_DEF) {
297 MI.eraseFromParent();
298 Changed = true;
299 continue;
300 }
301
302 // Replace tee instructions with local.tee. The difference is that tee
303 // instructions have two defs, while local.tee instructions have one def
304 // and an index of a local to write to.
305 //
306 // - Before:
307 // TeeReg, Reg = TEE DefReg
308 // INST ..., TeeReg, ...
309 // INST ..., Reg, ...
310 // INST ..., Reg, ...
311 // * DefReg: may or may not be stackified
312 // * Reg: not stackified
313 // * TeeReg: stackified
314 //
315 // - After (when DefReg was already stackified):
316 // TeeReg = LOCAL_TEE LocalId1, DefReg
317 // INST ..., TeeReg, ...
318 // INST ..., Reg, ...
319 // INST ..., Reg, ...
320 // * Reg: mapped to LocalId1
321 // * TeeReg: stackified
322 //
323 // - After (when DefReg was not already stackified):
324 // NewReg = LOCAL_GET LocalId1
325 // TeeReg = LOCAL_TEE LocalId2, NewReg
326 // INST ..., TeeReg, ...
327 // INST ..., Reg, ...
328 // INST ..., Reg, ...
329 // * DefReg: mapped to LocalId1
330 // * Reg: mapped to LocalId2
331 // * TeeReg: stackified
332 if (WebAssembly::isTee(MI.getOpcode())) {
333 assert(MFI.isVRegStackified(MI.getOperand(0).getReg()));
334 assert(!MFI.isVRegStackified(MI.getOperand(1).getReg()));
335 Register DefReg = MI.getOperand(2).getReg();
336 const TargetRegisterClass *RC = MRI.getRegClass(DefReg);
337
338 // Stackify the input if it isn't stackified yet.
339 if (!MFI.isVRegStackified(DefReg)) {
340 unsigned LocalId = getLocalId(Reg2Local, MFI, CurLocal, DefReg);
341 Register NewReg = MRI.createVirtualRegister(RC);
342 unsigned Opc = getLocalGetOpcode(RC);
343 BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(Opc), NewReg)
344 .addImm(LocalId);
345 MI.getOperand(2).setReg(NewReg);
346 MFI.stackifyVReg(MRI, NewReg);
347 }
348
349 // Replace the TEE with a LOCAL_TEE.
350 unsigned LocalId =
351 getLocalId(Reg2Local, MFI, CurLocal, MI.getOperand(1).getReg());
352 unsigned Opc = getLocalTeeOpcode(RC);
353 BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(Opc),
354 MI.getOperand(0).getReg())
355 .addImm(LocalId)
356 .addReg(MI.getOperand(2).getReg());
357
359
360 MI.eraseFromParent();
361 Changed = true;
362 continue;
363 }
364
365 // Insert local.sets for any defs that aren't stackified yet.
366 for (auto &Def : MI.defs()) {
367 Register OldReg = Def.getReg();
368 if (!MFI.isVRegStackified(OldReg)) {
369 const TargetRegisterClass *RC = MRI.getRegClass(OldReg);
370 Register NewReg = MRI.createVirtualRegister(RC);
371 auto InsertPt = std::next(MI.getIterator());
372 // When libcalls are emitted for thread context, the frame base vreg
373 // has an implicit use in the DW_AT_frame_base debug info, so we
374 // should not remove it.
375 bool NeedsRegForDebug =
376 MFI.isFrameBaseVirtual() && OldReg == MFI.getFrameBaseVreg() &&
377 MF.getFunction().getSubprogram() &&
378 MF.getSubtarget<WebAssemblySubtarget>().hasLibcallThreadContext();
379 if (UseEmpty[OldReg.virtRegIndex()] && !NeedsRegForDebug) {
380 unsigned Opc = getDropOpcode(RC);
381 MachineInstr *Drop =
382 BuildMI(MBB, InsertPt, MI.getDebugLoc(), TII->get(Opc))
383 .addReg(NewReg);
384 // After the drop instruction, this reg operand will not be used
385 Drop->getOperand(0).setIsKill();
386 if (MFI.isFrameBaseVirtual() && OldReg == MFI.getFrameBaseVreg())
387 MFI.clearFrameBaseVreg();
388 } else {
389 unsigned LocalId = getLocalId(Reg2Local, MFI, CurLocal, OldReg);
390 unsigned Opc = getLocalSetOpcode(RC);
391
393
394 BuildMI(MBB, InsertPt, MI.getDebugLoc(), TII->get(Opc))
395 .addImm(LocalId)
396 .addReg(NewReg);
397 }
398 // This register operand of the original instruction is now being used
399 // by the inserted drop or local.set instruction, so make it not dead
400 // yet.
401 Def.setReg(NewReg);
402 Def.setIsDead(false);
403 MFI.stackifyVReg(MRI, NewReg);
404 Changed = true;
405 }
406 }
407
408 // Insert local.gets for any uses that aren't stackified yet.
409 MachineInstr *InsertPt = &MI;
410 for (MachineOperand &MO : reverse(MI.explicit_uses())) {
411 if (!MO.isReg())
412 continue;
413
414 Register OldReg = MO.getReg();
415
416 // Inline asm may have a def in the middle of the operands. Our contract
417 // with inline asm register operands is to provide local indices as
418 // immediates.
419 if (MO.isDef()) {
420 assert(MI.isInlineAsm());
421 unsigned LocalId = getLocalId(Reg2Local, MFI, CurLocal, OldReg);
422 // If this register operand is tied to another operand, we can't
423 // change it to an immediate. Untie it first.
424 MI.untieRegOperand(MO.getOperandNo());
425 MO.ChangeToImmediate(LocalId);
426 continue;
427 }
428
429 // If we see a stackified register, prepare to insert subsequent
430 // local.gets before the start of its tree.
431 if (MFI.isVRegStackified(OldReg)) {
432 InsertPt = findStartOfTree(MO, MRI, MFI);
433 continue;
434 }
435
436 // Our contract with inline asm register operands is to provide local
437 // indices as immediates.
438 if (MI.isInlineAsm()) {
439 unsigned LocalId = getLocalId(Reg2Local, MFI, CurLocal, OldReg);
440 // Untie it first if this reg operand is tied to another operand.
441 MI.untieRegOperand(MO.getOperandNo());
442 MO.ChangeToImmediate(LocalId);
443 continue;
444 }
445
446 // Insert a local.get.
447 unsigned LocalId = getLocalId(Reg2Local, MFI, CurLocal, OldReg);
448 const TargetRegisterClass *RC = MRI.getRegClass(OldReg);
449 Register NewReg = MRI.createVirtualRegister(RC);
450 unsigned Opc = getLocalGetOpcode(RC);
451 // Use a InsertPt as our DebugLoc, since MI may be discontinuous from
452 // the where this local is being inserted, causing non-linear stepping
453 // in the debugger or function entry points where variables aren't live
454 // yet. Alternative is previous instruction, but that is strictly worse
455 // since it can point at the previous statement.
456 // See crbug.com/1251909, crbug.com/1249745
457 InsertPt = BuildMI(MBB, InsertPt, InsertPt->getDebugLoc(),
458 TII->get(Opc), NewReg).addImm(LocalId);
459 MO.setReg(NewReg);
460 MFI.stackifyVReg(MRI, NewReg);
461 Changed = true;
462 }
463
464 // Coalesce and eliminate COPY instructions.
465 if (WebAssembly::isCopy(MI.getOpcode())) {
466 MRI.replaceRegWith(MI.getOperand(1).getReg(),
467 MI.getOperand(0).getReg());
468 MI.eraseFromParent();
469 Changed = true;
470 }
471 }
472 }
473
474 // Define the locals.
475 // TODO: Sort the locals for better compression.
476 MFI.setNumLocals(CurLocal - MFI.getParams().size());
477 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I < E; ++I) {
479 auto RL = Reg2Local.find(Reg);
480 if (RL == Reg2Local.end() || RL->second < MFI.getParams().size())
481 continue;
482
483 MFI.setLocal(RL->second - MFI.getParams().size(),
485 Changed = true;
486 }
487
488#ifndef NDEBUG
489 // Assert that all registers have been stackified at this point.
490 for (const MachineBasicBlock &MBB : MF) {
491 for (const MachineInstr &MI : MBB) {
492 if (MI.isDebugInstr() || MI.isLabel())
493 continue;
494 for (const MachineOperand &MO : MI.explicit_operands()) {
495 assert(
496 (!MO.isReg() || MRI.use_empty(MO.getReg()) ||
497 MFI.isVRegStackified(MO.getReg())) &&
498 "WebAssemblyExplicitLocals failed to stackify a register operand");
499 }
500 }
501 }
502#endif
503
504 return Changed;
505}
506
507bool WebAssemblyExplicitLocalsLegacy::runOnMachineFunction(
508 MachineFunction &MF) {
509 return explicitLocals(MF);
510}
511
512PreservedAnalyses
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define DEBUG_TYPE
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define P(N)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
#define LLVM_DEBUG(...)
Definition Debug.h:119
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:
Definition Pass.cpp:275
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:223
iterator end()
Definition DenseMap.h:141
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:284
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
DISubprogram * getSubprogram() const
Get the attached subprogram.
Machine Value Type.
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.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
Wrapper class representing virtual and physical registers.
Definition Register.h:20
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition Register.h:72
unsigned virtRegIndex() const
Convert a virtual register number to a 0-based index.
Definition Register.h:87
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.
Definition StringRef.h:56
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
void stackifyVReg(MachineRegisterInfo &MRI, Register VReg)
const std::vector< MVT > & getLocals() const
const std::vector< MVT > & getParams() const
Changed
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.
Definition CallingConv.h:24
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.
Definition STLExtras.h:1669
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...
Definition STLExtras.h:633
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
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.
Definition Debug.cpp:209
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58