LLVM 23.0.0git
WebAssemblyRegStackify.cpp
Go to the documentation of this file.
1//===-- WebAssemblyRegStackify.cpp - Register Stackification --------------===//
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 implements a register stacking pass.
11///
12/// This pass reorders instructions to put register uses and defs in an order
13/// such that they form single-use expression trees. Registers fitting this form
14/// are then marked as "stackified", meaning references to them are replaced by
15/// "push" and "pop" from the value stack.
16///
17/// This is primarily a code size optimization, since temporary values on the
18/// value stack don't need to be named.
19///
20//===----------------------------------------------------------------------===//
21
22#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" // for WebAssembly::ARGUMENT_*
23#include "WebAssembly.h"
33#include "llvm/CodeGen/Passes.h"
34#include "llvm/IR/GlobalAlias.h"
35#include "llvm/Support/Debug.h"
37#include <iterator>
38using namespace llvm;
39
40#define DEBUG_TYPE "wasm-reg-stackify"
41
42namespace {
43class WebAssemblyRegStackify final : public MachineFunctionPass {
44 bool Optimize;
45
46 StringRef getPassName() const override {
47 return "WebAssembly Register Stackify";
48 }
49
50 void getAnalysisUsage(AnalysisUsage &AU) const override {
51 AU.setPreservesCFG();
52 if (Optimize) {
55 }
62 }
63
64 bool runOnMachineFunction(MachineFunction &MF) override;
65
66public:
67 static char ID; // Pass identification, replacement for typeid
68 WebAssemblyRegStackify(CodeGenOptLevel OptLevel)
70 WebAssemblyRegStackify() : WebAssemblyRegStackify(CodeGenOptLevel::Default) {}
71};
72} // end anonymous namespace
73
74char WebAssemblyRegStackify::ID = 0;
75INITIALIZE_PASS(WebAssemblyRegStackify, DEBUG_TYPE,
76 "Reorder instructions to use the WebAssembly value stack",
77 false, false)
78
80 return new WebAssemblyRegStackify(OptLevel);
81}
82
83// Decorate the given instruction with implicit operands that enforce the
84// expression stack ordering constraints for an instruction which is on
85// the expression stack.
87 // Write the opaque VALUE_STACK register.
88 if (!MI->definesRegister(WebAssembly::VALUE_STACK, /*TRI=*/nullptr))
89 MI->addOperand(MachineOperand::CreateReg(WebAssembly::VALUE_STACK,
90 /*isDef=*/true,
91 /*isImp=*/true));
92
93 // Also read the opaque VALUE_STACK register.
94 if (!MI->readsRegister(WebAssembly::VALUE_STACK, /*TRI=*/nullptr))
95 MI->addOperand(MachineOperand::CreateReg(WebAssembly::VALUE_STACK,
96 /*isDef=*/false,
97 /*isImp=*/true));
98}
99
100// Convert an IMPLICIT_DEF instruction into an instruction which defines
101// a constant zero value.
104 const TargetInstrInfo *TII,
105 MachineFunction &MF) {
106 assert(MI->getOpcode() == TargetOpcode::IMPLICIT_DEF);
107
108 const auto *RegClass = MRI.getRegClass(MI->getOperand(0).getReg());
109 if (RegClass == &WebAssembly::I32RegClass) {
110 MI->setDesc(TII->get(WebAssembly::CONST_I32));
111 MI->addOperand(MachineOperand::CreateImm(0));
112 } else if (RegClass == &WebAssembly::I64RegClass) {
113 MI->setDesc(TII->get(WebAssembly::CONST_I64));
114 MI->addOperand(MachineOperand::CreateImm(0));
115 } else if (RegClass == &WebAssembly::F32RegClass) {
116 MI->setDesc(TII->get(WebAssembly::CONST_F32));
119 MI->addOperand(MachineOperand::CreateFPImm(Val));
120 } else if (RegClass == &WebAssembly::F64RegClass) {
121 MI->setDesc(TII->get(WebAssembly::CONST_F64));
124 MI->addOperand(MachineOperand::CreateFPImm(Val));
125 } else if (RegClass == &WebAssembly::V128RegClass) {
126 MI->setDesc(TII->get(WebAssembly::CONST_V128_I64x2));
127 MI->addOperand(MachineOperand::CreateImm(0));
128 MI->addOperand(MachineOperand::CreateImm(0));
129 } else {
130 llvm_unreachable("Unexpected reg class");
131 }
132}
133
134// Determine whether a call to the callee referenced by
135// MI->getOperand(CalleeOpNo) reads memory, writes memory, and/or has side
136// effects.
137static void queryCallee(const MachineInstr &MI, bool &Read, bool &Write,
138 bool &Effects, bool &StackPointer) {
139 // All calls can use the stack pointer.
140 StackPointer = true;
141
143 if (MO.isGlobal()) {
144 const Constant *GV = MO.getGlobal();
145 if (const auto *GA = dyn_cast<GlobalAlias>(GV))
146 if (!GA->isInterposable())
147 GV = GA->getAliasee();
148
149 if (const auto *F = dyn_cast<Function>(GV)) {
150 if (!F->doesNotThrow())
151 Effects = true;
152 if (F->doesNotAccessMemory())
153 return;
154 if (F->onlyReadsMemory()) {
155 Read = true;
156 return;
157 }
158 }
159 }
160
161 // Assume the worst.
162 Write = true;
163 Read = true;
164 Effects = true;
165}
166
167// Determine whether MI reads memory, writes memory, has side effects,
168// and/or uses the stack pointer value.
169static void query(const MachineInstr &MI, bool &Read, bool &Write,
170 bool &Effects, bool &StackPointer) {
171 assert(!MI.isTerminator());
172
173 if (MI.isDebugInstr() || MI.isPosition())
174 return;
175
176 // Check for loads.
177 if (MI.mayLoad() && !MI.isDereferenceableInvariantLoad())
178 Read = true;
179
180 // Check for stores.
181 if (MI.mayStore()) {
182 Write = true;
183 } else if (MI.hasOrderedMemoryRef()) {
184 switch (MI.getOpcode()) {
185 case WebAssembly::DIV_S_I32:
186 case WebAssembly::DIV_S_I64:
187 case WebAssembly::REM_S_I32:
188 case WebAssembly::REM_S_I64:
189 case WebAssembly::DIV_U_I32:
190 case WebAssembly::DIV_U_I64:
191 case WebAssembly::REM_U_I32:
192 case WebAssembly::REM_U_I64:
193 case WebAssembly::I32_TRUNC_S_F32:
194 case WebAssembly::I64_TRUNC_S_F32:
195 case WebAssembly::I32_TRUNC_S_F64:
196 case WebAssembly::I64_TRUNC_S_F64:
197 case WebAssembly::I32_TRUNC_U_F32:
198 case WebAssembly::I64_TRUNC_U_F32:
199 case WebAssembly::I32_TRUNC_U_F64:
200 case WebAssembly::I64_TRUNC_U_F64:
201 // These instruction have hasUnmodeledSideEffects() returning true
202 // because they trap on overflow and invalid so they can't be arbitrarily
203 // moved, however hasOrderedMemoryRef() interprets this plus their lack
204 // of memoperands as having a potential unknown memory reference.
205 break;
206 default:
207 // Record volatile accesses, unless it's a call, as calls are handled
208 // specially below.
209 if (!MI.isCall()) {
210 Write = true;
211 Effects = true;
212 }
213 break;
214 }
215 }
216
217 // Check for side effects.
218 if (MI.hasUnmodeledSideEffects()) {
219 switch (MI.getOpcode()) {
220 case WebAssembly::DIV_S_I32:
221 case WebAssembly::DIV_S_I64:
222 case WebAssembly::REM_S_I32:
223 case WebAssembly::REM_S_I64:
224 case WebAssembly::DIV_U_I32:
225 case WebAssembly::DIV_U_I64:
226 case WebAssembly::REM_U_I32:
227 case WebAssembly::REM_U_I64:
228 case WebAssembly::I32_TRUNC_S_F32:
229 case WebAssembly::I64_TRUNC_S_F32:
230 case WebAssembly::I32_TRUNC_S_F64:
231 case WebAssembly::I64_TRUNC_S_F64:
232 case WebAssembly::I32_TRUNC_U_F32:
233 case WebAssembly::I64_TRUNC_U_F32:
234 case WebAssembly::I32_TRUNC_U_F64:
235 case WebAssembly::I64_TRUNC_U_F64:
236 // These instructions have hasUnmodeledSideEffects() returning true
237 // because they trap on overflow and invalid so they can't be arbitrarily
238 // moved, however in the specific case of register stackifying, it is safe
239 // to move them because overflow and invalid are Undefined Behavior.
240 break;
241 default:
242 Effects = true;
243 break;
244 }
245 }
246
247 // Check for writes to __stack_pointer global.
248 if ((MI.getOpcode() == WebAssembly::GLOBAL_SET_I32 ||
249 MI.getOpcode() == WebAssembly::GLOBAL_SET_I64) &&
250 MI.getOperand(0).isSymbol() &&
251 !strcmp(MI.getOperand(0).getSymbolName(), "__stack_pointer"))
252 StackPointer = true;
253
254 if (MI.isCall() && MI.getOperand(0).isSymbol() &&
255 !strcmp(MI.getOperand(0).getSymbolName(), "__wasm_get_stack_pointer"))
256 StackPointer = true;
257
258 // Analyze calls.
259 if (MI.isCall()) {
260 queryCallee(MI, Read, Write, Effects, StackPointer);
261 }
262}
263
264// Test whether Def is safe and profitable to rematerialize.
265static bool shouldRematerialize(const MachineInstr &Def,
266 const WebAssemblyInstrInfo *TII) {
267 return Def.isAsCheapAsAMove() && TII->isTriviallyReMaterializable(Def);
268}
269
270// Identify the definition for this register at this point. This is a
271// generalization of MachineRegisterInfo::getUniqueVRegDef that uses
272// LiveIntervals to handle complex cases.
273static MachineInstr *getVRegDef(unsigned Reg, const MachineInstr *Insert,
274 const MachineRegisterInfo &MRI,
275 const LiveIntervals *LIS) {
276 // Most registers are in SSA form here so we try a quick MRI query first.
277 if (MachineInstr *Def = MRI.getUniqueVRegDef(Reg))
278 return Def;
279
280 // MRI doesn't know what the Def is. Try asking LIS.
281 if (LIS != nullptr) {
282 SlotIndex InstIndex = LIS->getInstructionIndex(*Insert);
283 if (const VNInfo *ValNo = LIS->getInterval(Reg).getVNInfoBefore(InstIndex))
284 return LIS->getInstructionFromIndex(ValNo->def);
285 }
286
287 return nullptr;
288}
289
290// Test whether Reg, as defined at Def, has exactly one use. This is a
291// generalization of MachineRegisterInfo::hasOneNonDBGUse that uses
292// LiveIntervals to handle complex cases in optimized code.
293static bool hasSingleUse(unsigned Reg, MachineRegisterInfo &MRI,
294 const MachineFunction &MF, bool Optimize,
295 MachineInstr *Def, LiveIntervals *LIS) {
296 auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
297 // The frame base always has an implicit DBG use as DW_AT_frame_base.
298 if (MFI.isFrameBaseVirtual() && MFI.getFrameBaseVreg() == Reg) {
299 // When using global thread context, the frame base can be encoded
300 // as an offset from __stack_pointer, so the vreg can be stackified.
301 // However, when using libcall thread context, we need to keep the frame
302 // base vreg around if debug info is enabled, because there is no
303 // global to refer to.
304 bool NeedsRegForDebug =
305 MF.getFunction().getSubprogram() &&
306 MF.getSubtarget<WebAssemblySubtarget>().hasLibcallThreadContext();
307 if (!Optimize || NeedsRegForDebug)
308 return false;
309 }
310 if (!Optimize) {
311 // Using "hasOneUse" instead of "hasOneNonDBGUse" here because we don't
312 // want to stackify DBG_VALUE operands - WASM stack locations are less
313 // useful and less widely supported than WASM local locations.
314 if (!MRI.hasOneUse(Reg))
315 return false;
316 return true;
317 }
318
319 // Most registers are in SSA form here so we try a quick MRI query first.
320 if (MRI.hasOneNonDBGUse(Reg))
321 return true;
322
323 if (LIS == nullptr)
324 return false;
325
326 bool HasOne = false;
327 const LiveInterval &LI = LIS->getInterval(Reg);
328 const VNInfo *DefVNI =
330 assert(DefVNI);
331 for (auto &I : MRI.use_nodbg_operands(Reg)) {
332 const auto &Result = LI.Query(LIS->getInstructionIndex(*I.getParent()));
333 if (Result.valueIn() == DefVNI) {
334 if (!Result.isKill())
335 return false;
336 if (HasOne)
337 return false;
338 HasOne = true;
339 }
340 }
341 return HasOne;
342}
343
344// Test whether it's safe to move Def to just before Insert.
345// TODO: Compute memory dependencies in a way that doesn't require always
346// walking the block.
347// TODO: Compute memory dependencies in a way that uses AliasAnalysis to be
348// more precise.
349static bool isSafeToMove(const MachineOperand *Def, const MachineOperand *Use,
350 const MachineInstr *Insert,
351 const WebAssemblyFunctionInfo &MFI,
352 const MachineRegisterInfo &MRI, bool Optimize) {
353 const MachineInstr *DefI = Def->getParent();
354 const MachineInstr *UseI = Use->getParent();
355 assert(DefI->getParent() == Insert->getParent());
356 assert(UseI->getParent() == Insert->getParent());
357
358 // The first def of a multivalue instruction can be stackified by moving,
359 // since the later defs can always be placed into locals if necessary. Later
360 // defs can only be stackified if all previous defs are already stackified
361 // since ExplicitLocals will not know how to place a def in a local if a
362 // subsequent def is stackified. But only one def can be stackified by moving
363 // the instruction, so it must be the first one.
364 //
365 // TODO: This could be loosened to be the first *live* def, but care would
366 // have to be taken to ensure the drops of the initial dead defs can be
367 // placed. This would require checking that no previous defs are used in the
368 // same instruction as subsequent defs.
369 if (Def != DefI->defs().begin())
370 return false;
371
372 // If any subsequent def is used prior to the current value by the same
373 // instruction in which the current value is used, we cannot
374 // stackify. Stackifying in this case would require that def moving below the
375 // current def in the stack, which cannot be achieved, even with locals.
376 // Also ensure we don't sink the def past any other prior uses.
377 for (const auto &SubsequentDef : drop_begin(DefI->defs())) {
378 auto I = std::next(MachineBasicBlock::const_iterator(DefI));
379 auto E = std::next(MachineBasicBlock::const_iterator(UseI));
380 for (; I != E; ++I) {
381 for (const auto &PriorUse : I->uses()) {
382 if (&PriorUse == Use)
383 break;
384 if (PriorUse.isReg() && SubsequentDef.getReg() == PriorUse.getReg())
385 return false;
386 }
387 }
388 }
389
390 // If moving is a semantic nop, it is always allowed
391 const MachineBasicBlock *MBB = DefI->getParent();
392 auto NextI = std::next(MachineBasicBlock::const_iterator(DefI));
393 for (auto E = MBB->end(); NextI != E && NextI->isDebugInstr(); ++NextI)
394 ;
395 if (NextI == Insert)
396 return true;
397
398 // When not optimizing, we only handle the trivial case above
399 // to guarantee no impact to debugging and to avoid spending
400 // compile time.
401 if (!Optimize)
402 return false;
403
404 // 'catch' and 'catch_all' should be the first instruction of a BB and cannot
405 // move.
406 if (WebAssembly::isCatch(DefI->getOpcode()))
407 return false;
408
409 // Check for register dependencies.
410 SmallVector<unsigned, 4> MutableRegisters;
411 for (const MachineOperand &MO : DefI->operands()) {
412 if (!MO.isReg() || MO.isUndef())
413 continue;
414 Register Reg = MO.getReg();
415
416 // If the register is dead here and at Insert, ignore it.
417 if (MO.isDead() && Insert->definesRegister(Reg, /*TRI=*/nullptr) &&
418 !Insert->readsRegister(Reg, /*TRI=*/nullptr))
419 continue;
420
421 if (Reg.isPhysical()) {
422 // Ignore ARGUMENTS; it's just used to keep the ARGUMENT_* instructions
423 // from moving down, and we've already checked for that.
424 if (Reg == WebAssembly::ARGUMENTS)
425 continue;
426 // If the physical register is never modified, ignore it.
427 if (!MRI.isPhysRegModified(Reg))
428 continue;
429 // Otherwise, it's a physical register with unknown liveness.
430 return false;
431 }
432
433 // If one of the operands isn't in SSA form, it has different values at
434 // different times, and we need to make sure we don't move our use across
435 // a different def.
436 if (!MO.isDef() && !MRI.hasOneDef(Reg))
437 MutableRegisters.push_back(Reg);
438 }
439
440 bool Read = false, Write = false, Effects = false, StackPointer = false;
441 query(*DefI, Read, Write, Effects, StackPointer);
442
443 // If the instruction does not access memory and has no side effects, it has
444 // no additional dependencies.
445 bool HasMutableRegisters = !MutableRegisters.empty();
446 if (!Read && !Write && !Effects && !StackPointer && !HasMutableRegisters)
447 return true;
448
449 // Scan through the intervening instructions between DefI and Insert.
451 for (--I; I != D; --I) {
452 bool InterveningRead = false;
453 bool InterveningWrite = false;
454 bool InterveningEffects = false;
455 bool InterveningStackPointer = false;
456 query(*I, InterveningRead, InterveningWrite, InterveningEffects,
457 InterveningStackPointer);
458 if (Effects && InterveningEffects)
459 return false;
460 if (Read && InterveningWrite)
461 return false;
462 if (Write && (InterveningRead || InterveningWrite))
463 return false;
464 if (StackPointer && InterveningStackPointer)
465 return false;
466
467 for (unsigned Reg : MutableRegisters)
468 for (const MachineOperand &MO : I->operands())
469 if (MO.isReg() && MO.isDef() && MO.getReg() == Reg)
470 return false;
471 }
472
473 return true;
474}
475
476/// Test whether OneUse, a use of Reg, dominates all of Reg's other uses.
477static bool oneUseDominatesOtherUses(unsigned Reg, const MachineOperand &OneUse,
478 const MachineBasicBlock &MBB,
479 const MachineRegisterInfo &MRI,
480 const MachineDominatorTree &MDT,
481 LiveIntervals &LIS,
483 const LiveInterval &LI = LIS.getInterval(Reg);
484
485 const MachineInstr *OneUseInst = OneUse.getParent();
486 VNInfo *OneUseVNI = LI.getVNInfoBefore(LIS.getInstructionIndex(*OneUseInst));
487
488 for (const MachineOperand &Use : MRI.use_nodbg_operands(Reg)) {
489 if (&Use == &OneUse)
490 continue;
491
492 const MachineInstr *UseInst = Use.getParent();
493 VNInfo *UseVNI = LI.getVNInfoBefore(LIS.getInstructionIndex(*UseInst));
494
495 if (UseVNI != OneUseVNI)
496 continue;
497
498 if (UseInst == OneUseInst) {
499 // Another use in the same instruction. We need to ensure that the one
500 // selected use happens "before" it.
501 if (&OneUse > &Use)
502 return false;
503 } else {
504 // Test that the use is dominated by the one selected use.
505 while (!MDT.dominates(OneUseInst, UseInst)) {
506 // Actually, dominating is over-conservative. Test that the use would
507 // happen after the one selected use in the stack evaluation order.
508 //
509 // This is needed as a consequence of using implicit local.gets for
510 // uses and implicit local.sets for defs.
511 if (UseInst->getDesc().getNumDefs() == 0)
512 return false;
513 const MachineOperand &MO = UseInst->getOperand(0);
514 if (!MO.isReg())
515 return false;
516 Register DefReg = MO.getReg();
517 if (!DefReg.isVirtual() || !MFI.isVRegStackified(DefReg))
518 return false;
519 assert(MRI.hasOneNonDBGUse(DefReg));
520 const MachineOperand &NewUse = *MRI.use_nodbg_begin(DefReg);
521 const MachineInstr *NewUseInst = NewUse.getParent();
522 if (NewUseInst == OneUseInst) {
523 if (&OneUse > &NewUse)
524 return false;
525 break;
526 }
527 UseInst = NewUseInst;
528 }
529 }
530 }
531 return true;
532}
533
534/// Get the appropriate tee opcode for the given register class.
535static unsigned getTeeOpcode(const TargetRegisterClass *RC) {
536 if (RC == &WebAssembly::I32RegClass)
537 return WebAssembly::TEE_I32;
538 if (RC == &WebAssembly::I64RegClass)
539 return WebAssembly::TEE_I64;
540 if (RC == &WebAssembly::F32RegClass)
541 return WebAssembly::TEE_F32;
542 if (RC == &WebAssembly::F64RegClass)
543 return WebAssembly::TEE_F64;
544 if (RC == &WebAssembly::V128RegClass)
545 return WebAssembly::TEE_V128;
546 if (RC == &WebAssembly::EXTERNREFRegClass)
547 return WebAssembly::TEE_EXTERNREF;
548 if (RC == &WebAssembly::FUNCREFRegClass)
549 return WebAssembly::TEE_FUNCREF;
550 if (RC == &WebAssembly::EXNREFRegClass)
551 return WebAssembly::TEE_EXNREF;
552 llvm_unreachable("Unexpected register class");
553}
554
555// Shrink LI to its uses, cleaning up LI.
557 if (LIS.shrinkToUses(&LI)) {
559 LIS.splitSeparateComponents(LI, SplitLIs);
560 }
561}
562
563/// A single-use def in the same block with no intervening memory or register
564/// dependencies; move the def down and nest it with the current instruction.
567 MachineInstr *Insert, LiveIntervals *LIS,
569 MachineRegisterInfo &MRI) {
570 LLVM_DEBUG(dbgs() << "Move for single use: "; Def->dump());
571
573 DefDIs.sink(Insert);
574 if (LIS != nullptr)
575 LIS->handleMove(*Def);
576
577 if (MRI.hasOneDef(Reg) && MRI.hasOneNonDBGUse(Reg)) {
578 // No one else is using this register for anything so we can just stackify
579 // it in place.
580 MFI.stackifyVReg(MRI, Reg);
581 } else {
582 // The register may have unrelated uses or defs; create a new register for
583 // just our one def and use so that we can stackify it.
585 Op.setReg(NewReg);
586 DefDIs.updateReg(NewReg);
587
588 if (LIS != nullptr) {
589 // Tell LiveIntervals about the new register.
591
592 // Tell LiveIntervals about the changes to the old register.
593 LiveInterval &LI = LIS->getInterval(Reg);
595 LIS->getInstructionIndex(*Op.getParent()).getRegSlot(),
596 /*RemoveDeadValNo=*/true);
597 }
598
599 MFI.stackifyVReg(MRI, NewReg);
600 LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
601 }
602
604 return Def;
605}
606
608 for (auto *I = MI->getPrevNode(); I; I = I->getPrevNode())
609 if (!I->isDebugInstr())
610 return I;
611 return nullptr;
612}
613
614/// A trivially cloneable instruction; clone it and nest the new copy with the
615/// current instruction.
616static MachineInstr *
621 const WebAssemblyInstrInfo *TII) {
622 LLVM_DEBUG(dbgs() << "Rematerializing cheap def: "; Def.dump());
623 LLVM_DEBUG(dbgs() << " - for use in "; Op.getParent()->dump());
624
625 WebAssemblyDebugValueManager DefDIs(&Def);
626
628 DefDIs.cloneSink(&*Insert, NewReg);
629 Op.setReg(NewReg);
630 MachineInstr *Clone = getPrevNonDebugInst(&*Insert);
631 assert(Clone);
632 LIS.InsertMachineInstrInMaps(*Clone);
634 MFI.stackifyVReg(MRI, NewReg);
635 imposeStackOrdering(Clone);
636
637 LLVM_DEBUG(dbgs() << " - Cloned to "; Clone->dump());
638
639 // Shrink the interval.
640 bool IsDead = MRI.use_empty(Reg);
641 if (!IsDead) {
642 LiveInterval &LI = LIS.getInterval(Reg);
643 shrinkToUses(LI, LIS);
645 }
646
647 // If that was the last use of the original, delete the original.
648 if (IsDead) {
649 LLVM_DEBUG(dbgs() << " - Deleting original\n");
651 LIS.removePhysRegDefAt(MCRegister::from(WebAssembly::ARGUMENTS), Idx);
652 LIS.removeInterval(Reg);
654 DefDIs.removeDef();
655 }
656
657 return Clone;
658}
659
660/// A multiple-use def in the same block with no intervening memory or register
661/// dependencies; move the def down, nest it with the current instruction, and
662/// insert a tee to satisfy the rest of the uses. As an illustration, rewrite
663/// this:
664///
665/// Reg = INST ... // Def
666/// INST ..., Reg, ... // Insert
667/// INST ..., Reg, ...
668/// INST ..., Reg, ...
669///
670/// to this:
671///
672/// DefReg = INST ... // Def (to become the new Insert)
673/// TeeReg, Reg = TEE_... DefReg
674/// INST ..., TeeReg, ... // Insert
675/// INST ..., Reg, ...
676/// INST ..., Reg, ...
677///
678/// with DefReg and TeeReg stackified. This eliminates a local.get from the
679/// resulting code.
684 LLVM_DEBUG(dbgs() << "Move and tee for multi-use:"; Def->dump());
685
686 const auto *RegClass = MRI.getRegClass(Reg);
687 Register TeeReg = MRI.createVirtualRegister(RegClass);
688 Register DefReg = MRI.createVirtualRegister(RegClass);
689
690 // Move Def into place.
692 DefDIs.sink(Insert);
693 LIS.handleMove(*Def);
694
695 // Create the Tee and attach the registers.
696 MachineOperand &DefMO = Def->getOperand(0);
697 MachineInstr *Tee = BuildMI(MBB, Insert, Insert->getDebugLoc(),
698 TII->get(getTeeOpcode(RegClass)), TeeReg)
700 .addReg(DefReg, getUndefRegState(DefMO.isDead()));
701 Op.setReg(TeeReg);
702 DefDIs.updateReg(DefReg);
703 SlotIndex TeeIdx = LIS.InsertMachineInstrInMaps(*Tee).getRegSlot();
704 SlotIndex DefIdx = LIS.getInstructionIndex(*Def).getRegSlot();
705
706 // Tell LiveIntervals we moved the original vreg def from Def to Tee.
707 LiveInterval &LI = LIS.getInterval(Reg);
709 VNInfo *ValNo = LI.getVNInfoAt(DefIdx);
710 I->start = TeeIdx;
711 ValNo->def = TeeIdx;
712 shrinkToUses(LI, LIS);
713
714 // Finish stackifying the new regs.
717 MFI.stackifyVReg(MRI, DefReg);
718 MFI.stackifyVReg(MRI, TeeReg);
721
722 // Even though 'TeeReg, Reg = TEE ...', has two defs, we don't need to clone
723 // DBG_VALUEs for both of them, given that the latter will cancel the former
724 // anyway. Here we only clone DBG_VALUEs for TeeReg, which will be converted
725 // to a local index in ExplicitLocals pass.
726 DefDIs.cloneSink(Insert, TeeReg, /* CloneDef */ false);
727
728 LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
729 LLVM_DEBUG(dbgs() << " - Tee instruction: "; Tee->dump());
730 return Def;
731}
732
733namespace {
734/// A stack for walking the tree of instructions being built, visiting the
735/// MachineOperands in DFS order.
736class TreeWalkerState {
737 using mop_iterator = MachineInstr::mop_iterator;
738 using mop_reverse_iterator = std::reverse_iterator<mop_iterator>;
739 using RangeTy = iterator_range<mop_reverse_iterator>;
741
742public:
743 explicit TreeWalkerState(MachineInstr *Insert) {
744 const iterator_range<mop_iterator> &Range = Insert->explicit_uses();
745 if (!Range.empty())
746 Worklist.push_back(reverse(Range));
747 }
748
749 bool done() const { return Worklist.empty(); }
750
751 MachineOperand &pop() {
752 RangeTy &Range = Worklist.back();
753 MachineOperand &Op = *Range.begin();
755 if (Range.empty())
756 Worklist.pop_back();
757 assert((Worklist.empty() || !Worklist.back().empty()) &&
758 "Empty ranges shouldn't remain in the worklist");
759 return Op;
760 }
761
762 /// Push Instr's operands onto the stack to be visited.
763 void pushOperands(MachineInstr *Instr) {
764 const iterator_range<mop_iterator> &Range(Instr->explicit_uses());
765 if (!Range.empty())
766 Worklist.push_back(reverse(Range));
767 }
768
769 /// Some of Instr's operands are on the top of the stack; remove them and
770 /// re-insert them starting from the beginning (because we've commuted them).
771 void resetTopOperands(MachineInstr *Instr) {
772 assert(hasRemainingOperands(Instr) &&
773 "Reseting operands should only be done when the instruction has "
774 "an operand still on the stack");
775 Worklist.back() = reverse(Instr->explicit_uses());
776 }
777
778 /// Test whether Instr has operands remaining to be visited at the top of
779 /// the stack.
780 bool hasRemainingOperands(const MachineInstr *Instr) const {
781 if (Worklist.empty())
782 return false;
783 const RangeTy &Range = Worklist.back();
784 return !Range.empty() && Range.begin()->getParent() == Instr;
785 }
786
787 /// Test whether the given register is present on the stack, indicating an
788 /// operand in the tree that we haven't visited yet. Moving a definition of
789 /// Reg to a point in the tree after that would change its value.
790 ///
791 /// This is needed as a consequence of using implicit local.gets for
792 /// uses and implicit local.sets for defs.
793 bool isOnStack(unsigned Reg) const {
794 for (const RangeTy &Range : Worklist)
795 for (const MachineOperand &MO : Range)
796 if (MO.isReg() && MO.getReg() == Reg)
797 return true;
798 return false;
799 }
800};
801
802/// State to keep track of whether commuting is in flight or whether it's been
803/// tried for the current instruction and didn't work.
804class CommutingState {
805 /// There are effectively three states: the initial state where we haven't
806 /// started commuting anything and we don't know anything yet, the tentative
807 /// state where we've commuted the operands of the current instruction and are
808 /// revisiting it, and the declined state where we've reverted the operands
809 /// back to their original order and will no longer commute it further.
810 bool TentativelyCommuting = false;
811 bool Declined = false;
812
813 /// During the tentative state, these hold the operand indices of the commuted
814 /// operands.
815 unsigned Operand0, Operand1;
816
817public:
818 /// Stackification for an operand was not successful due to ordering
819 /// constraints. If possible, and if we haven't already tried it and declined
820 /// it, commute Insert's operands and prepare to revisit it.
821 void maybeCommute(MachineInstr *Insert, TreeWalkerState &TreeWalker,
822 const WebAssemblyInstrInfo *TII) {
823 if (TentativelyCommuting) {
824 assert(!Declined &&
825 "Don't decline commuting until you've finished trying it");
826 // Commuting didn't help. Revert it.
827 TII->commuteInstruction(*Insert, /*NewMI=*/false, Operand0, Operand1);
828 TentativelyCommuting = false;
829 Declined = true;
830 } else if (!Declined && TreeWalker.hasRemainingOperands(Insert)) {
833 if (TII->findCommutedOpIndices(*Insert, Operand0, Operand1)) {
834 // Tentatively commute the operands and try again.
835 TII->commuteInstruction(*Insert, /*NewMI=*/false, Operand0, Operand1);
836 TreeWalker.resetTopOperands(Insert);
837 TentativelyCommuting = true;
838 Declined = false;
839 }
840 }
841 }
842
843 /// Stackification for some operand was successful. Reset to the default
844 /// state.
845 void reset() {
846 TentativelyCommuting = false;
847 Declined = false;
848 }
849};
850} // end anonymous namespace
851
852bool WebAssemblyRegStackify::runOnMachineFunction(MachineFunction &MF) {
853 LLVM_DEBUG(dbgs() << "********** Register Stackifying **********\n"
854 "********** Function: "
855 << MF.getName() << '\n');
856
857 bool Changed = false;
858 MachineRegisterInfo &MRI = MF.getRegInfo();
859 WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
860 const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
861 MachineDominatorTree *MDT = nullptr;
862 LiveIntervals *LIS = nullptr;
863 if (Optimize) {
864 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
865 LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
866 }
867
868 // Walk the instructions from the bottom up. Currently we don't look past
869 // block boundaries, and the blocks aren't ordered so the block visitation
870 // order isn't significant, but we may want to change this in the future.
871 for (MachineBasicBlock &MBB : MF) {
872 // Don't use a range-based for loop, because we modify the list as we're
873 // iterating over it and the end iterator may change.
874 for (auto MII = MBB.rbegin(); MII != MBB.rend(); ++MII) {
875 MachineInstr *Insert = &*MII;
876 // Don't nest anything inside an inline asm, because we don't have
877 // constraints for $push inputs.
878 if (Insert->isInlineAsm())
879 continue;
880
881 // Ignore debugging intrinsics.
882 if (Insert->isDebugValue())
883 continue;
884
885 // Ignore FAKE_USEs, which are no-ops and will be deleted later.
886 if (Insert->isFakeUse())
887 continue;
888
889 // Iterate through the inputs in reverse order, since we'll be pulling
890 // operands off the stack in LIFO order.
891 CommutingState Commuting;
892 TreeWalkerState TreeWalker(Insert);
893 while (!TreeWalker.done()) {
894 MachineOperand &Use = TreeWalker.pop();
895
896 // We're only interested in explicit virtual register operands.
897 if (!Use.isReg())
898 continue;
899
900 Register Reg = Use.getReg();
901 assert(Use.isUse() && "explicit_uses() should only iterate over uses");
902 assert(!Use.isImplicit() &&
903 "explicit_uses() should only iterate over explicit operands");
904 if (Reg.isPhysical())
905 continue;
906
907 // Identify the definition for this register at this point.
908 MachineInstr *DefI = getVRegDef(Reg, Insert, MRI, LIS);
909 if (!DefI)
910 continue;
911
912 // Don't nest an INLINE_ASM def into anything, because we don't have
913 // constraints for $pop outputs.
914 if (DefI->isInlineAsm())
915 continue;
916
917 // Argument instructions represent live-in registers and not real
918 // instructions.
920 continue;
921
922 MachineOperand *Def =
923 DefI->findRegisterDefOperand(Reg, /*TRI=*/nullptr);
924 assert(Def != nullptr);
925
926 // Decide which strategy to take. Prefer to move a single-use value
927 // over cloning it, and prefer cloning over introducing a tee.
928 // For moving, we require the def to be in the same block as the use;
929 // this makes things simpler (LiveIntervals' handleMove function only
930 // supports intra-block moves) and it's MachineSink's job to catch all
931 // the sinking opportunities anyway.
932 bool SameBlock = DefI->getParent() == &MBB;
933 bool CanMove = SameBlock &&
934 isSafeToMove(Def, &Use, Insert, MFI, MRI, Optimize) &&
935 !TreeWalker.isOnStack(Reg);
936 if (CanMove && hasSingleUse(Reg, MRI, MF, Optimize, DefI, LIS)) {
937 Insert = moveForSingleUse(Reg, Use, DefI, MBB, Insert, LIS, MFI, MRI);
938
939 // If we are removing the frame base reg completely, remove the debug
940 // info as well.
941 // TODO: Encode this properly as a stackified value.
942 if (MFI.isFrameBaseVirtual() && MFI.getFrameBaseVreg() == Reg) {
943 assert(
944 Optimize &&
945 "Stackifying away frame base in unoptimized code not expected");
946 MFI.clearFrameBaseVreg();
947 }
948 } else if (Optimize && shouldRematerialize(*DefI, TII)) {
949 Insert = rematerializeCheapDef(Reg, Use, *DefI, Insert->getIterator(),
950 *LIS, MFI, MRI, TII);
951 } else if (Optimize && CanMove &&
952 oneUseDominatesOtherUses(Reg, Use, MBB, MRI, *MDT, *LIS,
953 MFI)) {
954 Insert = moveAndTeeForMultiUse(Reg, Use, DefI, MBB, Insert, *LIS, MFI,
955 MRI, TII);
956 } else {
957 // We failed to stackify the operand. If the problem was ordering
958 // constraints, Commuting may be able to help.
959 if (!CanMove && SameBlock)
960 Commuting.maybeCommute(Insert, TreeWalker, TII);
961 // Proceed to the next operand.
962 continue;
963 }
964
965 // Stackifying a multivalue def may unlock in-place stackification of
966 // subsequent defs. TODO: Handle the case where the consecutive uses are
967 // not all in the same instruction.
968 auto *SubsequentDef = Insert->defs().begin();
969 auto *SubsequentUse = &Use;
970 while (SubsequentDef != Insert->defs().end() &&
971 SubsequentUse != Use.getParent()->uses().end()) {
972 if (!SubsequentDef->isReg() || !SubsequentUse->isReg())
973 break;
974 Register DefReg = SubsequentDef->getReg();
975 Register UseReg = SubsequentUse->getReg();
976 // TODO: This single-use restriction could be relaxed by using tees
977 if (DefReg != UseReg ||
978 !hasSingleUse(DefReg, MRI, MF, Optimize, nullptr, nullptr))
979 break;
980 MFI.stackifyVReg(MRI, DefReg);
981 ++SubsequentDef;
982 ++SubsequentUse;
983 }
984
985 // If the instruction we just stackified is an IMPLICIT_DEF, convert it
986 // to a constant 0 so that the def is explicit, and the push/pop
987 // correspondence is maintained.
988 if (Insert->getOpcode() == TargetOpcode::IMPLICIT_DEF)
989 convertImplicitDefToConstZero(Insert, MRI, TII, MF);
990
991 // We stackified an operand. Add the defining instruction's operands to
992 // the worklist stack now to continue to build an ever deeper tree.
993 Commuting.reset();
994 TreeWalker.pushOperands(Insert);
995 }
996
997 // If we stackified any operands, skip over the tree to start looking for
998 // the next instruction we can build a tree on.
999 if (Insert != &*MII) {
1000 imposeStackOrdering(&*MII);
1002 Changed = true;
1003 }
1004 }
1005 }
1006
1007 // If we used VALUE_STACK anywhere, add it to the live-in sets everywhere so
1008 // that it never looks like a use-before-def.
1009 if (Changed) {
1010 MF.getRegInfo().addLiveIn(WebAssembly::VALUE_STACK);
1011 for (MachineBasicBlock &MBB : MF)
1012 MBB.addLiveIn(WebAssembly::VALUE_STACK);
1013 }
1014
1015#ifndef NDEBUG
1016 // Verify that pushes and pops are performed in LIFO order.
1017 SmallVector<unsigned, 0> Stack;
1018 for (MachineBasicBlock &MBB : MF) {
1019 for (MachineInstr &MI : MBB) {
1020 if (MI.isDebugInstr())
1021 continue;
1022 for (MachineOperand &MO : reverse(MI.explicit_uses())) {
1023 if (!MO.isReg())
1024 continue;
1025 Register Reg = MO.getReg();
1026 if (MFI.isVRegStackified(Reg))
1027 assert(Stack.pop_back_val() == Reg &&
1028 "Register stack pop should be paired with a push");
1029 }
1030 for (MachineOperand &MO : MI.defs()) {
1031 if (!MO.isReg())
1032 continue;
1033 Register Reg = MO.getReg();
1034 if (MFI.isVRegStackified(Reg))
1035 Stack.push_back(MO.getReg());
1036 }
1037 }
1038 // TODO: Generalize this code to support keeping values on the stack across
1039 // basic block boundaries.
1040 assert(Stack.empty() &&
1041 "Register stack pushes and pops should be balanced");
1042 }
1043#endif
1044
1045 return Changed;
1046}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define DEBUG_TYPE
static Register UseReg(const MachineOperand &MO)
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Promote Memory to Register
Definition Mem2Reg.cpp:110
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
bool IsDead
#define LLVM_DEBUG(...)
Definition Debug.h:119
This file contains the declaration of the WebAssembly-specific manager for DebugValues associated wit...
This file provides WebAssembly-specific target descriptions.
This file declares WebAssembly-specific per-machine-function information.
static bool isSafeToMove(const MachineOperand *Def, const MachineOperand *Use, const MachineInstr *Insert, const WebAssemblyFunctionInfo &MFI, const MachineRegisterInfo &MRI, bool Optimize)
static unsigned getTeeOpcode(const TargetRegisterClass *RC)
Get the appropriate tee opcode for the given register class.
static MachineInstr * rematerializeCheapDef(unsigned Reg, MachineOperand &Op, MachineInstr &Def, MachineBasicBlock::instr_iterator Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII)
A trivially cloneable instruction; clone it and nest the new copy with the current instruction.
static bool hasSingleUse(unsigned Reg, MachineRegisterInfo &MRI, const MachineFunction &MF, bool Optimize, MachineInstr *Def, LiveIntervals *LIS)
static void imposeStackOrdering(MachineInstr *MI)
static MachineInstr * moveForSingleUse(unsigned Reg, MachineOperand &Op, MachineInstr *Def, MachineBasicBlock &MBB, MachineInstr *Insert, LiveIntervals *LIS, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI)
A single-use def in the same block with no intervening memory or register dependencies; move the def ...
static void query(const MachineInstr &MI, bool &Read, bool &Write, bool &Effects, bool &StackPointer)
static void shrinkToUses(LiveInterval &LI, LiveIntervals &LIS)
static void convertImplicitDefToConstZero(MachineInstr *MI, MachineRegisterInfo &MRI, const TargetInstrInfo *TII, MachineFunction &MF)
static MachineInstr * getPrevNonDebugInst(MachineInstr *MI)
static bool shouldRematerialize(const MachineInstr &Def, const WebAssemblyInstrInfo *TII)
static MachineInstr * moveAndTeeForMultiUse(unsigned Reg, MachineOperand &Op, MachineInstr *Def, MachineBasicBlock &MBB, MachineInstr *Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII)
A multiple-use def in the same block with no intervening memory or register dependencies; move the de...
static bool oneUseDominatesOtherUses(unsigned Reg, const MachineOperand &OneUse, const MachineBasicBlock &MBB, const MachineRegisterInfo &MRI, const MachineDominatorTree &MDT, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI)
Test whether OneUse, a use of Reg, dominates all of Reg's other uses.
static void queryCallee(const MachineInstr &MI, bool &Read, bool &Write, bool &Effects, bool &StackPointer)
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 & addPreservedID(const void *ID)
AnalysisUsage & addRequired()
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:270
This is an important base class in LLVM.
Definition Constant.h:43
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
DISubprogram * getSubprogram() const
Get the attached subprogram.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:358
LiveInterval - This class represents the liveness of a register, or stack slot.
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
LLVM_ABI void handleMove(MachineInstr &MI, bool UpdateFlags=false)
Call this method to notify LiveIntervals that instruction MI has been moved within a basic block.
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
LiveInterval & getInterval(Register Reg)
void removeInterval(Register Reg)
Interval removal.
LLVM_ABI bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr * > *dead=nullptr)
After removing some uses of a register, shrink its live range to just the remaining uses.
LLVM_ABI void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos)
Remove value numbers and related live segments starting at position Pos that are part of any liverang...
LLVM_ABI void splitSeparateComponents(LiveInterval &LI, SmallVectorImpl< LiveInterval * > &SplitLIs)
Split separate components in LiveInterval LI into separate intervals.
LiveInterval & createAndComputeVirtRegInterval(Register Reg)
Segments::iterator iterator
bool liveAt(SlotIndex index) const
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
VNInfo * getVNInfoBefore(SlotIndex Idx) const
getVNInfoBefore - Return the VNInfo that is live up to but not necessarily including Idx,...
iterator FindSegmentContaining(SlotIndex Idx)
Return an iterator to the segment that contains the specified index, or end() if there is none.
LLVM_ABI void removeSegment(SlotIndex Start, SlotIndex End, bool RemoveDeadValNo=false)
Remove the specified interval from this live range.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
static MCRegister from(unsigned Val)
Check the provided unsigned value is a valid MCRegister.
Definition MCRegister.h:77
MachineInstrBundleIterator< const MachineInstr > const_iterator
Instructions::iterator instr_iterator
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
reverse_iterator rbegin()
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) const
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.
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Representation of each machine instruction.
mop_range defs()
Returns all explicit operands that are register definitions.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
bool isInlineAsm() const
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
mop_range operands()
MachineOperand * mop_iterator
iterator/begin/end - Iterate over all operands of a machine instruction.
LLVM_ABI void dump() const
const MachineOperand & getOperand(unsigned i) const
MachineOperand * findRegisterDefOperand(Register Reg, const TargetRegisterInfo *TRI, bool isDead=false, bool Overlap=false)
Wrapper for findRegisterDefOperandIdx, it returns a pointer to the MachineOperand rather than an inde...
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
static MachineOperand CreateFPImm(const ConstantFP *CFP)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static MachineOperand CreateImm(int64_t Val)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
use_nodbg_iterator use_nodbg_begin(Register RegNo) const
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
iterator_range< use_nodbg_iterator > use_nodbg_operands(Register Reg) const
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
bool hasOneDef(Register RegNo) const
Return true if there is exactly one operand defining the specified register.
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
LLVM_ABI bool isPhysRegModified(MCRegister PhysReg, bool SkipNoReturnDef=false) const
Return true if the specified register is modified in this function.
LLVM_ABI MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:79
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:83
SlotIndex - An opaque wrapper around machine indexes.
Definition SlotIndexes.h:66
SlotIndex getDeadSlot() const
Returns the dead def kill slot for the current instruction.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
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
TargetInstrInfo - Interface to description of machine instruction set.
static const unsigned CommuteAnyOperandIndex
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
Definition Type.cpp:287
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
Definition Type.cpp:286
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
VNInfo - Value Number Information.
SlotIndex def
The index of the defining instruction.
void cloneSink(MachineInstr *Insert, Register NewReg=Register(), bool CloneDef=true) const
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
void stackifyVReg(MachineRegisterInfo &MRI, Register VReg)
IteratorT begin() const
Changed
#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)
const MachineOperand & getCalleeOp(const MachineInstr &MI)
Returns the operand number of a callee, assuming the argument is a call instruction.
bool isCatch(unsigned Opc)
NodeAddr< DefNode * > Def
Definition RDFGraph.h:384
NodeAddr< InstrNode * > Instr
Definition RDFGraph.h:389
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:315
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Define
Register definition.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
FunctionPass * createWebAssemblyRegStackify(CodeGenOptLevel OptLevel)
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:82
@ Default
-O2, -Os, -Oz
Definition CodeGen.h:85
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
DWARFExpression::Operation Op
LLVM_ABI char & LiveVariablesID
LiveVariables pass - This pass computes the set of blocks in which each variable is life and sets mac...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)
constexpr RegState getUndefRegState(bool B)